GlobalISel: move type information to MachineRegisterInfo.
We want each register to have a canonical type, which means the best place to
store this is in MachineRegisterInfo rather than on every MachineInstr that
happens to use or define that register.
Most changes following from this are pretty simple (you need an MRI anyway if
you're going to be doing any transformations, so just check the type there).
But legalization doesn't really want to check redundant operands (when, for
example, a G_ADD only ever has one type) so I've made use of MCInstrDesc's
operand type field to encode these constraints and limit legalization's work.
As an added bonus, more validation is possible, both in MachineVerifier and
MachineIRBuilder (coming soon).
llvm-svn: 281035
diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
index f0ac167..5a8f519 100644
--- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
@@ -55,8 +55,7 @@
// we need to concat together to produce the value.
assert(Val.getType()->isSized() &&
"Don't know how to create an empty vreg");
- unsigned Size = DL->getTypeSizeInBits(Val.getType());
- unsigned VReg = MRI->createGenericVirtualRegister(Size);
+ unsigned VReg = MRI->createGenericVirtualRegister(LLT{*Val.getType(), DL});
ValReg = VReg;
if (auto CV = dyn_cast<Constant>(&Val)) {
@@ -113,10 +112,7 @@
unsigned Op0 = getOrCreateVReg(*U.getOperand(0));
unsigned Op1 = getOrCreateVReg(*U.getOperand(1));
unsigned Res = getOrCreateVReg(U);
- MIRBuilder.buildInstr(Opcode, LLT{*U.getType()})
- .addDef(Res)
- .addUse(Op0)
- .addUse(Op1);
+ MIRBuilder.buildInstr(Opcode).addDef(Res).addUse(Op0).addUse(Op1);
return true;
}
@@ -130,13 +126,9 @@
cast<ConstantExpr>(U).getPredicate());
if (CmpInst::isIntPredicate(Pred))
- MIRBuilder.buildICmp(
- {LLT{*U.getType()}, LLT{*U.getOperand(0)->getType()}}, Pred, Res, Op0,
- Op1);
+ MIRBuilder.buildICmp(Pred, Res, Op0, Op1);
else
- MIRBuilder.buildFCmp(
- {LLT{*U.getType()}, LLT{*U.getOperand(0)->getType()}}, Pred, Res, Op0,
- Op1);
+ MIRBuilder.buildFCmp(Pred, Res, Op0, Op1);
return true;
}
@@ -158,7 +150,7 @@
unsigned Tst = getOrCreateVReg(*BrInst.getCondition());
const BasicBlock &TrueTgt = *cast<BasicBlock>(BrInst.getSuccessor(Succ++));
MachineBasicBlock &TrueBB = getOrCreateBB(TrueTgt);
- MIRBuilder.buildBrCond(LLT{*BrInst.getCondition()->getType()}, Tst, TrueBB);
+ MIRBuilder.buildBrCond(Tst, TrueBB);
}
const BasicBlock &BrTgt = *cast<BasicBlock>(BrInst.getSuccessor(Succ));
@@ -186,7 +178,7 @@
LLT VTy{*LI.getType(), DL}, PTy{*LI.getPointerOperand()->getType()};
MIRBuilder.buildLoad(
- VTy, PTy, Res, Addr,
+ Res, Addr,
*MF.getMachineMemOperand(
MachinePointerInfo(LI.getPointerOperand()), MachineMemOperand::MOLoad,
DL->getTypeStoreSize(LI.getType()), getMemOpAlignment(LI)));
@@ -208,7 +200,7 @@
PTy{*SI.getPointerOperand()->getType()};
MIRBuilder.buildStore(
- VTy, PTy, Val, Addr,
+ Val, Addr,
*MF.getMachineMemOperand(
MachinePointerInfo(SI.getPointerOperand()),
MachineMemOperand::MOStore,
@@ -237,8 +229,7 @@
uint64_t Offset = 8 * DL->getIndexedOffsetInType(Src->getType(), Indices);
unsigned Res = getOrCreateVReg(U);
- MIRBuilder.buildExtract(LLT{*U.getType(), DL}, Res, Offset,
- LLT{*Src->getType(), DL}, getOrCreateVReg(*Src));
+ MIRBuilder.buildExtract(Res, Offset, getOrCreateVReg(*Src));
return true;
}
@@ -264,17 +255,16 @@
unsigned Res = getOrCreateVReg(U);
const Value &Inserted = *U.getOperand(1);
- MIRBuilder.buildInsert(LLT{*U.getType(), DL}, Res, getOrCreateVReg(*Src),
- LLT{*Inserted.getType(), DL},
- getOrCreateVReg(Inserted), Offset);
+ MIRBuilder.buildInsert(Res, getOrCreateVReg(*Src), getOrCreateVReg(Inserted),
+ Offset);
return true;
}
bool IRTranslator::translateSelect(const User &U) {
- MIRBuilder.buildSelect(
- LLT{*U.getType()}, getOrCreateVReg(U), getOrCreateVReg(*U.getOperand(0)),
- getOrCreateVReg(*U.getOperand(1)), getOrCreateVReg(*U.getOperand(2)));
+ MIRBuilder.buildSelect(getOrCreateVReg(U), getOrCreateVReg(*U.getOperand(0)),
+ getOrCreateVReg(*U.getOperand(1)),
+ getOrCreateVReg(*U.getOperand(2)));
return true;
}
@@ -293,10 +283,7 @@
bool IRTranslator::translateCast(unsigned Opcode, const User &U) {
unsigned Op = getOrCreateVReg(*U.getOperand(0));
unsigned Res = getOrCreateVReg(U);
- MIRBuilder
- .buildInstr(Opcode, {LLT{*U.getType()}, LLT{*U.getOperand(0)->getType()}})
- .addDef(Res)
- .addUse(Op);
+ MIRBuilder.buildInstr(Opcode).addDef(Res).addUse(Op);
return true;
}
@@ -316,22 +303,21 @@
LLT Ty{*CI.getOperand(0)->getType()};
LLT s1 = LLT::scalar(1);
unsigned Width = Ty.getSizeInBits();
- unsigned Res = MRI->createGenericVirtualRegister(Width);
- unsigned Overflow = MRI->createGenericVirtualRegister(1);
- auto MIB = MIRBuilder.buildInstr(Op, {Ty, s1})
+ unsigned Res = MRI->createGenericVirtualRegister(Ty);
+ unsigned Overflow = MRI->createGenericVirtualRegister(s1);
+ auto MIB = MIRBuilder.buildInstr(Op)
.addDef(Res)
.addDef(Overflow)
.addUse(getOrCreateVReg(*CI.getOperand(0)))
.addUse(getOrCreateVReg(*CI.getOperand(1)));
if (Op == TargetOpcode::G_UADDE || Op == TargetOpcode::G_USUBE) {
- unsigned Zero = MRI->createGenericVirtualRegister(1);
- EntryBuilder.buildConstant(s1, Zero, 0);
+ unsigned Zero = MRI->createGenericVirtualRegister(s1);
+ EntryBuilder.buildConstant(Zero, 0);
MIB.addUse(Zero);
}
- MIRBuilder.buildSequence(LLT{*CI.getType(), DL}, getOrCreateVReg(CI), Ty, Res,
- 0, s1, Overflow, Width);
+ MIRBuilder.buildSequence(getOrCreateVReg(CI), Res, 0, Overflow, Width);
return true;
}
@@ -361,15 +347,9 @@
if (translateKnownIntrinsic(CI, ID))
return true;
- // Need types (starting with return) & args.
- SmallVector<LLT, 4> Tys;
- Tys.emplace_back(*CI.getType());
- for (auto &Arg : CI.arg_operands())
- Tys.emplace_back(*Arg->getType());
-
unsigned Res = CI.getType()->isVoidTy() ? 0 : getOrCreateVReg(CI);
MachineInstrBuilder MIB =
- MIRBuilder.buildIntrinsic(Tys, ID, Res, !CI.doesNotAccessMemory());
+ MIRBuilder.buildIntrinsic(ID, Res, !CI.doesNotAccessMemory());
for (auto &Arg : CI.arg_operands()) {
if (ConstantInt *CI = dyn_cast<ConstantInt>(Arg))
@@ -399,13 +379,13 @@
unsigned Res = getOrCreateVReg(AI);
int FI = MF.getFrameInfo().CreateStackObject(Size, Alignment, false, &AI);
- MIRBuilder.buildFrameIndex(LLT::pointer(0), Res, FI);
+ MIRBuilder.buildFrameIndex(Res, FI);
return true;
}
bool IRTranslator::translatePHI(const User &U) {
const PHINode &PI = cast<PHINode>(U);
- auto MIB = MIRBuilder.buildInstr(TargetOpcode::G_PHI, LLT{*U.getType()});
+ auto MIB = MIRBuilder.buildInstr(TargetOpcode::G_PHI);
MIB.addDef(getOrCreateVReg(PI));
PendingPHIs.emplace_back(&PI, MIB.getInstr());
@@ -447,13 +427,13 @@
bool IRTranslator::translate(const Constant &C, unsigned Reg) {
if (auto CI = dyn_cast<ConstantInt>(&C))
- EntryBuilder.buildConstant(LLT{*CI->getType()}, Reg, CI->getZExtValue());
+ EntryBuilder.buildConstant(Reg, CI->getZExtValue());
else if (auto CF = dyn_cast<ConstantFP>(&C))
- EntryBuilder.buildFConstant(LLT{*CF->getType()}, Reg, *CF);
+ EntryBuilder.buildFConstant(Reg, *CF);
else if (isa<UndefValue>(C))
EntryBuilder.buildInstr(TargetOpcode::IMPLICIT_DEF).addDef(Reg);
else if (isa<ConstantPointerNull>(C))
- EntryBuilder.buildInstr(TargetOpcode::G_CONSTANT, LLT{*C.getType()})
+ EntryBuilder.buildInstr(TargetOpcode::G_CONSTANT)
.addDef(Reg)
.addImm(0);
else if (auto CE = dyn_cast<ConstantExpr>(&C)) {
diff --git a/llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp b/llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp
index 1cc7556..70d4dd7 100644
--- a/llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp
@@ -75,10 +75,11 @@
// The RegBankSelected property is already checked in the verifier. Note
// that it has the same layering problem, but we only use inline methods so
// end up not needing to link against the GlobalISel library.
+ const MachineRegisterInfo &MRI = MF.getRegInfo();
if (const MachineLegalizer *MLI = MF.getSubtarget().getMachineLegalizer())
for (const MachineBasicBlock &MBB : MF)
for (const MachineInstr &MI : MBB)
- if (isPreISelGenericOpcode(MI.getOpcode()) && !MLI->isLegal(MI))
+ if (isPreISelGenericOpcode(MI.getOpcode()) && !MLI->isLegal(MI, MRI))
reportSelectionError(MI, "Instruction is not legal");
#endif
@@ -118,7 +119,7 @@
// the vreg instead, but that's not ideal either, because it's saying that
// vregs have types, which they really don't. But then again, LLT is just
// a size and a "shape": it's probably the same information as regbank info.
- MF.getRegInfo().clearVirtRegSizes();
+ MF.getRegInfo().clearVirtRegTypes();
// FIXME: Should we accurately track changes?
return true;
diff --git a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
index da18b03..eb34581 100644
--- a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
@@ -14,6 +14,7 @@
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetOpcodes.h"
#include "llvm/Target/TargetSubtargetInfo.h"
@@ -23,6 +24,7 @@
void MachineIRBuilder::setMF(MachineFunction &MF) {
this->MF = &MF;
this->MBB = nullptr;
+ this->MRI = &MF.getRegInfo();
this->TII = MF.getSubtarget().getInstrInfo();
this->DL = DebugLoc();
this->MI = nullptr;
@@ -67,100 +69,87 @@
// Build instruction variants.
//------------------------------------------------------------------------------
-MachineInstrBuilder MachineIRBuilder::buildInstr(unsigned Opcode,
- ArrayRef<LLT> Tys) {
+MachineInstrBuilder MachineIRBuilder::buildInstr(unsigned Opcode) {
MachineInstrBuilder MIB = BuildMI(getMF(), DL, getTII().get(Opcode));
- if (Tys.size() > 0) {
- assert(isPreISelGenericOpcode(Opcode) &&
- "Only generic instruction can have a type");
- for (unsigned i = 0; i < Tys.size(); ++i)
- MIB->setType(Tys[i], i);
- } else
- assert(!isPreISelGenericOpcode(Opcode) &&
- "Generic instruction must have a type");
getMBB().insert(getInsertPt(), MIB);
if (InsertedInstr)
InsertedInstr(MIB);
return MIB;
}
-MachineInstrBuilder MachineIRBuilder::buildFrameIndex(LLT Ty, unsigned Res,
- int Idx) {
- return buildInstr(TargetOpcode::G_FRAME_INDEX, Ty)
+MachineInstrBuilder MachineIRBuilder::buildFrameIndex(unsigned Res, int Idx) {
+ return buildInstr(TargetOpcode::G_FRAME_INDEX)
.addDef(Res)
.addFrameIndex(Idx);
}
-MachineInstrBuilder MachineIRBuilder::buildAdd(LLT Ty, unsigned Res,
- unsigned Op0, unsigned Op1) {
- return buildInstr(TargetOpcode::G_ADD, Ty)
+MachineInstrBuilder MachineIRBuilder::buildAdd(unsigned Res, unsigned Op0,
+ unsigned Op1) {
+ return buildInstr(TargetOpcode::G_ADD)
.addDef(Res)
.addUse(Op0)
.addUse(Op1);
}
-MachineInstrBuilder MachineIRBuilder::buildSub(LLT Ty, unsigned Res,
- unsigned Op0, unsigned Op1) {
- return buildInstr(TargetOpcode::G_SUB, Ty)
+MachineInstrBuilder MachineIRBuilder::buildSub(unsigned Res, unsigned Op0,
+ unsigned Op1) {
+ return buildInstr(TargetOpcode::G_SUB)
.addDef(Res)
.addUse(Op0)
.addUse(Op1);
}
-MachineInstrBuilder MachineIRBuilder::buildMul(LLT Ty, unsigned Res,
- unsigned Op0, unsigned Op1) {
- return buildInstr(TargetOpcode::G_MUL, Ty)
+MachineInstrBuilder MachineIRBuilder::buildMul(unsigned Res, unsigned Op0,
+ unsigned Op1) {
+ return buildInstr(TargetOpcode::G_MUL)
.addDef(Res)
.addUse(Op0)
.addUse(Op1);
}
MachineInstrBuilder MachineIRBuilder::buildBr(MachineBasicBlock &Dest) {
- return buildInstr(TargetOpcode::G_BR, LLT::unsized()).addMBB(&Dest);
+ return buildInstr(TargetOpcode::G_BR).addMBB(&Dest);
}
MachineInstrBuilder MachineIRBuilder::buildCopy(unsigned Res, unsigned Op) {
return buildInstr(TargetOpcode::COPY).addDef(Res).addUse(Op);
}
-MachineInstrBuilder MachineIRBuilder::buildConstant(LLT Ty, unsigned Res,
- int64_t Val) {
- return buildInstr(TargetOpcode::G_CONSTANT, Ty).addDef(Res).addImm(Val);
+MachineInstrBuilder MachineIRBuilder::buildConstant(unsigned Res, int64_t Val) {
+ return buildInstr(TargetOpcode::G_CONSTANT).addDef(Res).addImm(Val);
}
-MachineInstrBuilder MachineIRBuilder::buildFConstant(LLT Ty, unsigned Res,
- const ConstantFP &Val) {
- return buildInstr(TargetOpcode::G_FCONSTANT, Ty).addDef(Res).addFPImm(&Val);
+MachineInstrBuilder MachineIRBuilder::buildFConstant(unsigned Res,
+ const ConstantFP &Val) {
+ return buildInstr(TargetOpcode::G_FCONSTANT).addDef(Res).addFPImm(&Val);
}
-MachineInstrBuilder MachineIRBuilder::buildBrCond(LLT Ty, unsigned Tst,
+MachineInstrBuilder MachineIRBuilder::buildBrCond(unsigned Tst,
MachineBasicBlock &Dest) {
- return buildInstr(TargetOpcode::G_BRCOND, Ty).addUse(Tst).addMBB(&Dest);
+ return buildInstr(TargetOpcode::G_BRCOND).addUse(Tst).addMBB(&Dest);
}
-
- MachineInstrBuilder MachineIRBuilder::buildLoad(LLT VTy, LLT PTy, unsigned Res,
- unsigned Addr,
- MachineMemOperand &MMO) {
- return buildInstr(TargetOpcode::G_LOAD, {VTy, PTy})
+MachineInstrBuilder MachineIRBuilder::buildLoad(unsigned Res, unsigned Addr,
+ MachineMemOperand &MMO) {
+ return buildInstr(TargetOpcode::G_LOAD)
.addDef(Res)
.addUse(Addr)
.addMemOperand(&MMO);
}
-MachineInstrBuilder MachineIRBuilder::buildStore(LLT VTy, LLT PTy,
- unsigned Val, unsigned Addr,
- MachineMemOperand &MMO) {
- return buildInstr(TargetOpcode::G_STORE, {VTy, PTy})
+MachineInstrBuilder MachineIRBuilder::buildStore(unsigned Val, unsigned Addr,
+ MachineMemOperand &MMO) {
+ return buildInstr(TargetOpcode::G_STORE)
.addUse(Val)
.addUse(Addr)
.addMemOperand(&MMO);
}
-MachineInstrBuilder
-MachineIRBuilder::buildUAdde(ArrayRef<LLT> Tys, unsigned Res, unsigned CarryOut,
- unsigned Op0, unsigned Op1, unsigned CarryIn) {
- return buildInstr(TargetOpcode::G_UADDE, Tys)
+MachineInstrBuilder MachineIRBuilder::buildUAdde(unsigned Res,
+ unsigned CarryOut,
+ unsigned Op0, unsigned Op1,
+ unsigned CarryIn) {
+ return buildInstr(TargetOpcode::G_UADDE)
.addDef(Res)
.addDef(CarryOut)
.addUse(Op0)
@@ -168,44 +157,34 @@
.addUse(CarryIn);
}
-MachineInstrBuilder MachineIRBuilder::buildType(LLT Ty,
- unsigned Res, unsigned Op) {
- return buildInstr(TargetOpcode::G_TYPE, Ty).addDef(Res).addUse(Op);
+MachineInstrBuilder MachineIRBuilder::buildType(unsigned Res, unsigned Op) {
+ return buildInstr(TargetOpcode::G_TYPE).addDef(Res).addUse(Op);
}
-MachineInstrBuilder MachineIRBuilder::buildAnyExt(ArrayRef<LLT> Tys,
- unsigned Res, unsigned Op) {
- validateTruncExt(Tys, true);
- return buildInstr(TargetOpcode::G_ANYEXT, Tys).addDef(Res).addUse(Op);
+MachineInstrBuilder MachineIRBuilder::buildAnyExt(unsigned Res, unsigned Op) {
+ validateTruncExt(Res, Op, true);
+ return buildInstr(TargetOpcode::G_ANYEXT).addDef(Res).addUse(Op);
}
-MachineInstrBuilder MachineIRBuilder::buildSExt(ArrayRef<LLT> Tys, unsigned Res,
- unsigned Op) {
- validateTruncExt(Tys, true);
- return buildInstr(TargetOpcode::G_SEXT, Tys).addDef(Res).addUse(Op);
+MachineInstrBuilder MachineIRBuilder::buildSExt(unsigned Res, unsigned Op) {
+ validateTruncExt(Res, Op, true);
+ return buildInstr(TargetOpcode::G_SEXT).addDef(Res).addUse(Op);
}
-MachineInstrBuilder MachineIRBuilder::buildZExt(ArrayRef<LLT> Tys, unsigned Res,
- unsigned Op) {
- validateTruncExt(Tys, true);
- return buildInstr(TargetOpcode::G_ZEXT, Tys).addDef(Res).addUse(Op);
+MachineInstrBuilder MachineIRBuilder::buildZExt(unsigned Res, unsigned Op) {
+ validateTruncExt(Res, Op, true);
+ return buildInstr(TargetOpcode::G_ZEXT).addDef(Res).addUse(Op);
}
-MachineInstrBuilder MachineIRBuilder::buildExtract(ArrayRef<LLT> ResTys,
- ArrayRef<unsigned> Results,
+MachineInstrBuilder MachineIRBuilder::buildExtract(ArrayRef<unsigned> Results,
ArrayRef<uint64_t> Indices,
- LLT SrcTy, unsigned Src) {
- assert(ResTys.size() == Results.size() && Results.size() == Indices.size() &&
- "inconsistent number of regs");
+ unsigned Src) {
+ assert(Results.size() == Indices.size() && "inconsistent number of regs");
assert(!Results.empty() && "invalid trivial extract");
assert(std::is_sorted(Indices.begin(), Indices.end()) &&
"extract offsets must be in ascending order");
auto MIB = BuildMI(getMF(), DL, getTII().get(TargetOpcode::G_EXTRACT));
- for (unsigned i = 0; i < ResTys.size(); ++i)
- MIB->setType(LLT::scalar(ResTys[i].getSizeInBits()), i);
- MIB->setType(LLT::scalar(SrcTy.getSizeInBits()), ResTys.size());
-
for (auto Res : Results)
MIB.addDef(Res);
@@ -222,89 +201,79 @@
}
MachineInstrBuilder
-MachineIRBuilder::buildSequence(LLT ResTy, unsigned Res,
- ArrayRef<LLT> OpTys,
+MachineIRBuilder::buildSequence(unsigned Res,
ArrayRef<unsigned> Ops,
ArrayRef<unsigned> Indices) {
- assert(OpTys.size() == Ops.size() && Ops.size() == Indices.size() &&
- "incompatible args");
+ assert(Ops.size() == Indices.size() && "incompatible args");
assert(!Ops.empty() && "invalid trivial sequence");
assert(std::is_sorted(Indices.begin(), Indices.end()) &&
"sequence offsets must be in ascending order");
- MachineInstrBuilder MIB =
- buildInstr(TargetOpcode::G_SEQUENCE, LLT::scalar(ResTy.getSizeInBits()));
+ MachineInstrBuilder MIB = buildInstr(TargetOpcode::G_SEQUENCE);
MIB.addDef(Res);
for (unsigned i = 0; i < Ops.size(); ++i) {
MIB.addUse(Ops[i]);
MIB.addImm(Indices[i]);
- MIB->setType(LLT::scalar(OpTys[i].getSizeInBits()), MIB->getNumTypes());
}
return MIB;
}
-MachineInstrBuilder MachineIRBuilder::buildIntrinsic(ArrayRef<LLT> Tys,
- Intrinsic::ID ID,
+MachineInstrBuilder MachineIRBuilder::buildIntrinsic(Intrinsic::ID ID,
unsigned Res,
bool HasSideEffects) {
auto MIB =
buildInstr(HasSideEffects ? TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS
- : TargetOpcode::G_INTRINSIC,
- Tys);
+ : TargetOpcode::G_INTRINSIC);
if (Res)
MIB.addDef(Res);
MIB.addIntrinsicID(ID);
return MIB;
}
-MachineInstrBuilder MachineIRBuilder::buildTrunc(ArrayRef<LLT> Tys,
- unsigned Res, unsigned Op) {
- validateTruncExt(Tys, false);
- return buildInstr(TargetOpcode::G_TRUNC, Tys).addDef(Res).addUse(Op);
+MachineInstrBuilder MachineIRBuilder::buildTrunc(unsigned Res, unsigned Op) {
+ validateTruncExt(Res, Op, false);
+ return buildInstr(TargetOpcode::G_TRUNC).addDef(Res).addUse(Op);
}
-MachineInstrBuilder MachineIRBuilder::buildFPTrunc(ArrayRef<LLT> Tys,
- unsigned Res, unsigned Op) {
- validateTruncExt(Tys, false);
- return buildInstr(TargetOpcode::G_FPTRUNC, Tys).addDef(Res).addUse(Op);
+MachineInstrBuilder MachineIRBuilder::buildFPTrunc(unsigned Res, unsigned Op) {
+ validateTruncExt(Res, Op, false);
+ return buildInstr(TargetOpcode::G_FPTRUNC).addDef(Res).addUse(Op);
}
-MachineInstrBuilder MachineIRBuilder::buildICmp(ArrayRef<LLT> Tys,
- CmpInst::Predicate Pred,
+MachineInstrBuilder MachineIRBuilder::buildICmp(CmpInst::Predicate Pred,
unsigned Res, unsigned Op0,
unsigned Op1) {
- return buildInstr(TargetOpcode::G_ICMP, Tys)
+ return buildInstr(TargetOpcode::G_ICMP)
.addDef(Res)
.addPredicate(Pred)
.addUse(Op0)
.addUse(Op1);
}
-MachineInstrBuilder MachineIRBuilder::buildFCmp(ArrayRef<LLT> Tys,
- CmpInst::Predicate Pred,
+MachineInstrBuilder MachineIRBuilder::buildFCmp(CmpInst::Predicate Pred,
unsigned Res, unsigned Op0,
unsigned Op1) {
- return buildInstr(TargetOpcode::G_FCMP, Tys)
+ return buildInstr(TargetOpcode::G_FCMP)
.addDef(Res)
.addPredicate(Pred)
.addUse(Op0)
.addUse(Op1);
}
-MachineInstrBuilder MachineIRBuilder::buildSelect(LLT Ty, unsigned Res,
- unsigned Tst,
+MachineInstrBuilder MachineIRBuilder::buildSelect(unsigned Res, unsigned Tst,
unsigned Op0, unsigned Op1) {
- return buildInstr(TargetOpcode::G_SELECT, {Ty, LLT::scalar(1)})
+ return buildInstr(TargetOpcode::G_SELECT)
.addDef(Res)
.addUse(Tst)
.addUse(Op0)
.addUse(Op1);
}
-void MachineIRBuilder::validateTruncExt(ArrayRef<LLT> Tys, bool IsExtend) {
+void MachineIRBuilder::validateTruncExt(unsigned Dst, unsigned Src,
+ bool IsExtend) {
#ifndef NDEBUG
- assert(Tys.size() == 2 && "cast should have a source and a dest type");
- LLT DstTy{Tys[0]}, SrcTy{Tys[1]};
+ LLT SrcTy = MRI->getType(Src);
+ LLT DstTy = MRI->getType(Dst);
if (DstTy.isVector()) {
assert(SrcTy.isVector() && "mismatched cast between vecot and non-vector");
diff --git a/llvm/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp b/llvm/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp
index 18db91c..c5872f5 100644
--- a/llvm/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp
@@ -36,7 +36,7 @@
MachineLegalizeHelper::LegalizeResult
MachineLegalizeHelper::legalizeInstrStep(MachineInstr &MI,
const MachineLegalizer &Legalizer) {
- auto Action = Legalizer.getAction(MI);
+ auto Action = Legalizer.getAction(MI, MRI);
switch (std::get<0>(Action)) {
case MachineLegalizer::Legal:
return AlreadyLegal;
@@ -85,19 +85,17 @@
SmallVectorImpl<unsigned> &VRegs) {
unsigned Size = Ty.getSizeInBits();
SmallVector<uint64_t, 4> Indexes;
- SmallVector<LLT, 4> ResTys;
for (int i = 0; i < NumParts; ++i) {
- VRegs.push_back(MRI.createGenericVirtualRegister(Size));
+ VRegs.push_back(MRI.createGenericVirtualRegister(Ty));
Indexes.push_back(i * Size);
- ResTys.push_back(Ty);
}
- MIRBuilder.buildExtract(ResTys, VRegs, Indexes,
- LLT::scalar(Ty.getSizeInBits() * NumParts), Reg);
+ MIRBuilder.buildExtract(VRegs, Indexes, Reg);
}
MachineLegalizeHelper::LegalizeResult
MachineLegalizeHelper::libcall(MachineInstr &MI) {
- unsigned Size = MI.getType().getSizeInBits();
+ LLT Ty = MRI.getType(MI.getOperand(0).getReg());
+ unsigned Size = Ty.getSizeInBits();
MIRBuilder.setInstr(MI);
switch (MI.getOpcode()) {
@@ -132,7 +130,8 @@
case TargetOpcode::G_ADD: {
// Expand in terms of carry-setting/consuming G_ADDE instructions.
unsigned NarrowSize = NarrowTy.getSizeInBits();
- int NumParts = MI.getType().getSizeInBits() / NarrowSize;
+ int NumParts = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits() /
+ NarrowTy.getSizeInBits();
MIRBuilder.setInstr(MI);
@@ -140,24 +139,22 @@
extractParts(MI.getOperand(1).getReg(), NarrowTy, NumParts, Src1Regs);
extractParts(MI.getOperand(2).getReg(), NarrowTy, NumParts, Src2Regs);
- unsigned CarryIn = MRI.createGenericVirtualRegister(1);
- MIRBuilder.buildConstant(LLT::scalar(1), CarryIn, 0);
+ unsigned CarryIn = MRI.createGenericVirtualRegister(LLT::scalar(1));
+ MIRBuilder.buildConstant(CarryIn, 0);
- SmallVector<LLT, 2> DstTys;
for (int i = 0; i < NumParts; ++i) {
- unsigned DstReg = MRI.createGenericVirtualRegister(NarrowSize);
- unsigned CarryOut = MRI.createGenericVirtualRegister(1);
+ unsigned DstReg = MRI.createGenericVirtualRegister(NarrowTy);
+ unsigned CarryOut = MRI.createGenericVirtualRegister(LLT::scalar(1));
- MIRBuilder.buildUAdde(NarrowTy, DstReg, CarryOut, Src1Regs[i],
+ MIRBuilder.buildUAdde(DstReg, CarryOut, Src1Regs[i],
Src2Regs[i], CarryIn);
- DstTys.push_back(NarrowTy);
DstRegs.push_back(DstReg);
Indexes.push_back(i * NarrowSize);
CarryIn = CarryOut;
}
- MIRBuilder.buildSequence(MI.getType(), MI.getOperand(0).getReg(), DstTys,
- DstRegs, Indexes);
+ unsigned DstReg = MI.getOperand(0).getReg();
+ MIRBuilder.buildSequence(DstReg, DstRegs, Indexes);
MI.eraseFromParent();
return Legalized;
}
@@ -167,7 +164,7 @@
MachineLegalizeHelper::LegalizeResult
MachineLegalizeHelper::widenScalar(MachineInstr &MI, unsigned TypeIdx,
LLT WideTy) {
- LLT Ty = MI.getType();
+ LLT Ty = MRI.getType(MI.getOperand(0).getReg());
unsigned WideSize = WideTy.getSizeInBits();
MIRBuilder.setInstr(MI);
@@ -183,16 +180,18 @@
// Perform operation at larger width (any extension is fine here, high bits
// don't affect the result) and then truncate the result back to the
// original type.
- unsigned Src1Ext = MRI.createGenericVirtualRegister(WideSize);
- unsigned Src2Ext = MRI.createGenericVirtualRegister(WideSize);
- MIRBuilder.buildAnyExt({WideTy, Ty}, Src1Ext, MI.getOperand(1).getReg());
- MIRBuilder.buildAnyExt({WideTy, Ty}, Src2Ext, MI.getOperand(2).getReg());
+ unsigned Src1Ext = MRI.createGenericVirtualRegister(WideTy);
+ unsigned Src2Ext = MRI.createGenericVirtualRegister(WideTy);
+ MIRBuilder.buildAnyExt(Src1Ext, MI.getOperand(1).getReg());
+ MIRBuilder.buildAnyExt(Src2Ext, MI.getOperand(2).getReg());
- unsigned DstExt = MRI.createGenericVirtualRegister(WideSize);
- MIRBuilder.buildInstr(MI.getOpcode(), WideTy)
- .addDef(DstExt).addUse(Src1Ext).addUse(Src2Ext);
+ unsigned DstExt = MRI.createGenericVirtualRegister(WideTy);
+ MIRBuilder.buildInstr(MI.getOpcode())
+ .addDef(DstExt)
+ .addUse(Src1Ext)
+ .addUse(Src2Ext);
- MIRBuilder.buildTrunc({Ty, WideTy}, MI.getOperand(0).getReg(), DstExt);
+ MIRBuilder.buildTrunc(MI.getOperand(0).getReg(), DstExt);
MI.eraseFromParent();
return Legalized;
}
@@ -202,24 +201,21 @@
? TargetOpcode::G_SEXT
: TargetOpcode::G_ZEXT;
- unsigned LHSExt = MRI.createGenericVirtualRegister(WideSize);
- MIRBuilder.buildInstr(ExtOp, {WideTy, MI.getType()})
- .addDef(LHSExt)
- .addUse(MI.getOperand(1).getReg());
+ unsigned LHSExt = MRI.createGenericVirtualRegister(WideTy);
+ MIRBuilder.buildInstr(ExtOp).addDef(LHSExt).addUse(
+ MI.getOperand(1).getReg());
- unsigned RHSExt = MRI.createGenericVirtualRegister(WideSize);
- MIRBuilder.buildInstr(ExtOp, {WideTy, MI.getType()})
- .addDef(RHSExt)
- .addUse(MI.getOperand(2).getReg());
+ unsigned RHSExt = MRI.createGenericVirtualRegister(WideTy);
+ MIRBuilder.buildInstr(ExtOp).addDef(RHSExt).addUse(
+ MI.getOperand(2).getReg());
- unsigned ResExt = MRI.createGenericVirtualRegister(WideSize);
- MIRBuilder.buildInstr(MI.getOpcode(), WideTy)
+ unsigned ResExt = MRI.createGenericVirtualRegister(WideTy);
+ MIRBuilder.buildInstr(MI.getOpcode())
.addDef(ResExt)
.addUse(LHSExt)
.addUse(RHSExt);
- MIRBuilder.buildTrunc({MI.getType(), WideTy}, MI.getOperand(0).getReg(),
- ResExt);
+ MIRBuilder.buildTrunc(MI.getOperand(0).getReg(), ResExt);
MI.eraseFromParent();
return Legalized;
}
@@ -227,10 +223,10 @@
assert(alignTo(Ty.getSizeInBits(), 8) == WideSize &&
"illegal to increase number of bytes loaded");
- unsigned DstExt = MRI.createGenericVirtualRegister(WideSize);
- MIRBuilder.buildLoad(WideTy, MI.getType(1), DstExt,
- MI.getOperand(1).getReg(), **MI.memoperands_begin());
- MIRBuilder.buildTrunc({Ty, WideTy}, MI.getOperand(0).getReg(), DstExt);
+ unsigned DstExt = MRI.createGenericVirtualRegister(WideTy);
+ MIRBuilder.buildLoad(DstExt, MI.getOperand(1).getReg(),
+ **MI.memoperands_begin());
+ MIRBuilder.buildTrunc(MI.getOperand(0).getReg(), DstExt);
MI.eraseFromParent();
return Legalized;
}
@@ -238,31 +234,31 @@
assert(alignTo(Ty.getSizeInBits(), 8) == WideSize &&
"illegal to increase number of bytes modified by a store");
- unsigned SrcExt = MRI.createGenericVirtualRegister(WideSize);
- MIRBuilder.buildAnyExt({WideTy, Ty}, SrcExt, MI.getOperand(0).getReg());
- MIRBuilder.buildStore(WideTy, MI.getType(1), SrcExt,
- MI.getOperand(1).getReg(), **MI.memoperands_begin());
+ unsigned SrcExt = MRI.createGenericVirtualRegister(WideTy);
+ MIRBuilder.buildAnyExt(SrcExt, MI.getOperand(0).getReg());
+ MIRBuilder.buildStore(SrcExt, MI.getOperand(1).getReg(),
+ **MI.memoperands_begin());
MI.eraseFromParent();
return Legalized;
}
case TargetOpcode::G_CONSTANT: {
- unsigned DstExt = MRI.createGenericVirtualRegister(WideSize);
- MIRBuilder.buildConstant(WideTy, DstExt, MI.getOperand(1).getImm());
- MIRBuilder.buildTrunc({Ty, WideTy}, MI.getOperand(0).getReg(), DstExt);
+ unsigned DstExt = MRI.createGenericVirtualRegister(WideTy);
+ MIRBuilder.buildConstant(DstExt, MI.getOperand(1).getImm());
+ MIRBuilder.buildTrunc(MI.getOperand(0).getReg(), DstExt);
MI.eraseFromParent();
return Legalized;
}
case TargetOpcode::G_FCONSTANT: {
- unsigned DstExt = MRI.createGenericVirtualRegister(WideSize);
- MIRBuilder.buildFConstant(WideTy, DstExt, *MI.getOperand(1).getFPImm());
- MIRBuilder.buildFPTrunc({Ty, WideTy}, MI.getOperand(0).getReg(), DstExt);
+ unsigned DstExt = MRI.createGenericVirtualRegister(WideTy);
+ MIRBuilder.buildFConstant(DstExt, *MI.getOperand(1).getFPImm());
+ MIRBuilder.buildFPTrunc(MI.getOperand(0).getReg(), DstExt);
MI.eraseFromParent();
return Legalized;
}
case TargetOpcode::G_BRCOND: {
- unsigned TstExt = MRI.createGenericVirtualRegister(WideSize);
- MIRBuilder.buildAnyExt({WideTy, Ty}, TstExt, MI.getOperand(0).getReg());
- MIRBuilder.buildBrCond(WideTy, TstExt, *MI.getOperand(1).getMBB());
+ unsigned TstExt = MRI.createGenericVirtualRegister(WideTy);
+ MIRBuilder.buildAnyExt(TstExt, MI.getOperand(0).getReg());
+ MIRBuilder.buildBrCond(TstExt, *MI.getOperand(1).getMBB());
MI.eraseFromParent();
return Legalized;
}
@@ -270,21 +266,16 @@
assert(TypeIdx == 1 && "unable to legalize predicate");
bool IsSigned = CmpInst::isSigned(
static_cast<CmpInst::Predicate>(MI.getOperand(1).getPredicate()));
- unsigned Op0Ext = MRI.createGenericVirtualRegister(WideSize);
- unsigned Op1Ext = MRI.createGenericVirtualRegister(WideSize);
+ unsigned Op0Ext = MRI.createGenericVirtualRegister(WideTy);
+ unsigned Op1Ext = MRI.createGenericVirtualRegister(WideTy);
if (IsSigned) {
- MIRBuilder.buildSExt({WideTy, MI.getType(1)}, Op0Ext,
- MI.getOperand(2).getReg());
- MIRBuilder.buildSExt({WideTy, MI.getType(1)}, Op1Ext,
- MI.getOperand(3).getReg());
+ MIRBuilder.buildSExt(Op0Ext, MI.getOperand(2).getReg());
+ MIRBuilder.buildSExt(Op1Ext, MI.getOperand(3).getReg());
} else {
- MIRBuilder.buildZExt({WideTy, MI.getType(1)}, Op0Ext,
- MI.getOperand(2).getReg());
- MIRBuilder.buildZExt({WideTy, MI.getType(1)}, Op1Ext,
- MI.getOperand(3).getReg());
+ MIRBuilder.buildZExt(Op0Ext, MI.getOperand(2).getReg());
+ MIRBuilder.buildZExt(Op1Ext, MI.getOperand(3).getReg());
}
MIRBuilder.buildICmp(
- {MI.getType(0), WideTy},
static_cast<CmpInst::Predicate>(MI.getOperand(1).getPredicate()),
MI.getOperand(0).getReg(), Op0Ext, Op1Ext);
MI.eraseFromParent();
@@ -296,7 +287,6 @@
MachineLegalizeHelper::LegalizeResult
MachineLegalizeHelper::lower(MachineInstr &MI, unsigned TypeIdx, LLT Ty) {
using namespace TargetOpcode;
- unsigned Size = Ty.getSizeInBits();
MIRBuilder.setInstr(MI);
switch(MI.getOpcode()) {
@@ -304,16 +294,16 @@
return UnableToLegalize;
case TargetOpcode::G_SREM:
case TargetOpcode::G_UREM: {
- unsigned QuotReg = MRI.createGenericVirtualRegister(Size);
- MIRBuilder.buildInstr(MI.getOpcode() == G_SREM ? G_SDIV : G_UDIV, Ty)
+ unsigned QuotReg = MRI.createGenericVirtualRegister(Ty);
+ MIRBuilder.buildInstr(MI.getOpcode() == G_SREM ? G_SDIV : G_UDIV)
.addDef(QuotReg)
.addUse(MI.getOperand(1).getReg())
.addUse(MI.getOperand(2).getReg());
- unsigned ProdReg = MRI.createGenericVirtualRegister(Size);
- MIRBuilder.buildMul(Ty, ProdReg, QuotReg, MI.getOperand(2).getReg());
- MIRBuilder.buildSub(Ty, MI.getOperand(0).getReg(),
- MI.getOperand(1).getReg(), ProdReg);
+ unsigned ProdReg = MRI.createGenericVirtualRegister(Ty);
+ MIRBuilder.buildMul(ProdReg, QuotReg, MI.getOperand(2).getReg());
+ MIRBuilder.buildSub(MI.getOperand(0).getReg(), MI.getOperand(1).getReg(),
+ ProdReg);
MI.eraseFromParent();
return Legalized;
}
@@ -331,7 +321,8 @@
return UnableToLegalize;
case TargetOpcode::G_ADD: {
unsigned NarrowSize = NarrowTy.getSizeInBits();
- int NumParts = MI.getType().getSizeInBits() / NarrowSize;
+ unsigned DstReg = MI.getOperand(0).getReg();
+ int NumParts = MRI.getType(DstReg).getSizeInBits() / NarrowSize;
MIRBuilder.setInstr(MI);
@@ -339,17 +330,14 @@
extractParts(MI.getOperand(1).getReg(), NarrowTy, NumParts, Src1Regs);
extractParts(MI.getOperand(2).getReg(), NarrowTy, NumParts, Src2Regs);
- SmallVector<LLT, 2> DstTys;
for (int i = 0; i < NumParts; ++i) {
- unsigned DstReg = MRI.createGenericVirtualRegister(NarrowSize);
- MIRBuilder.buildAdd(NarrowTy, DstReg, Src1Regs[i], Src2Regs[i]);
- DstTys.push_back(NarrowTy);
+ unsigned DstReg = MRI.createGenericVirtualRegister(NarrowTy);
+ MIRBuilder.buildAdd(DstReg, Src1Regs[i], Src2Regs[i]);
DstRegs.push_back(DstReg);
Indexes.push_back(i * NarrowSize);
}
- MIRBuilder.buildSequence(MI.getType(), MI.getOperand(0).getReg(), DstTys,
- DstRegs, Indexes);
+ MIRBuilder.buildSequence(DstReg, DstRegs, Indexes);
MI.eraseFromParent();
return Legalized;
}
diff --git a/llvm/lib/CodeGen/GlobalISel/MachineLegalizePass.cpp b/llvm/lib/CodeGen/GlobalISel/MachineLegalizePass.cpp
index b0de76d..b52cb10 100644
--- a/llvm/lib/CodeGen/GlobalISel/MachineLegalizePass.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/MachineLegalizePass.cpp
@@ -77,14 +77,18 @@
SeqI.getOperand(2 * SeqIdx + 2).getImm() < ExtractPos)
++SeqIdx;
- if (SeqIdx == NumSeqSrcs ||
- SeqI.getOperand(2 * SeqIdx + 2).getImm() != ExtractPos ||
- SeqI.getType(SeqIdx + 1) != MI.getType(Idx)) {
+ if (SeqIdx == NumSeqSrcs) {
AllDefsReplaced = false;
continue;
}
unsigned OrigReg = SeqI.getOperand(2 * SeqIdx + 1).getReg();
+ if (SeqI.getOperand(2 * SeqIdx + 2).getImm() != ExtractPos ||
+ MRI.getType(OrigReg) != MRI.getType(ExtractReg)) {
+ AllDefsReplaced = false;
+ continue;
+ }
+
assert(!TargetRegisterInfo::isPhysicalRegister(OrigReg) &&
"unexpected physical register in G_SEQUENCE");
diff --git a/llvm/lib/CodeGen/GlobalISel/MachineLegalizer.cpp b/llvm/lib/CodeGen/GlobalISel/MachineLegalizer.cpp
index 5a15f65..786decc 100644
--- a/llvm/lib/CodeGen/GlobalISel/MachineLegalizer.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/MachineLegalizer.cpp
@@ -18,7 +18,10 @@
//===----------------------------------------------------------------------===//
#include "llvm/CodeGen/GlobalISel/MachineLegalizer.h"
+
+#include "llvm/ADT/SmallBitVector.h"
#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/IR/Type.h"
#include "llvm/Target/TargetOpcodes.h"
@@ -116,17 +119,33 @@
}
std::tuple<MachineLegalizer::LegalizeAction, unsigned, LLT>
-MachineLegalizer::getAction(const MachineInstr &MI) const {
- for (unsigned i = 0; i < MI.getNumTypes(); ++i) {
- auto Action = getAction({MI.getOpcode(), i, MI.getType(i)});
+MachineLegalizer::getAction(const MachineInstr &MI,
+ const MachineRegisterInfo &MRI) const {
+ SmallBitVector SeenTypes(8);
+ const MCOperandInfo *OpInfo = MI.getDesc().OpInfo;
+ for (unsigned i = 0; i < MI.getDesc().getNumOperands(); ++i) {
+ if (!OpInfo[i].isGenericType())
+ continue;
+
+ // We don't want to repeatedly check the same operand index, that
+ // could get expensive.
+ unsigned TypeIdx = OpInfo[i].getGenericTypeIndex();
+ if (SeenTypes[TypeIdx])
+ continue;
+
+ SeenTypes.set(TypeIdx);
+
+ LLT Ty = MRI.getType(MI.getOperand(i).getReg());
+ auto Action = getAction({MI.getOpcode(), TypeIdx, Ty});
if (Action.first != Legal)
- return std::make_tuple(Action.first, i, Action.second);
+ return std::make_tuple(Action.first, TypeIdx, Action.second);
}
return std::make_tuple(Legal, 0, LLT{});
}
-bool MachineLegalizer::isLegal(const MachineInstr &MI) const {
- return std::get<0>(getAction(MI)) == Legal;
+bool MachineLegalizer::isLegal(const MachineInstr &MI,
+ const MachineRegisterInfo &MRI) const {
+ return std::get<0>(getAction(MI, MRI)) == Legal;
}
LLT MachineLegalizer::findLegalType(const InstrAspect &Aspect,
diff --git a/llvm/lib/CodeGen/GlobalISel/RegBankSelect.cpp b/llvm/lib/CodeGen/GlobalISel/RegBankSelect.cpp
index f20ff54..78d7cf7 100644
--- a/llvm/lib/CodeGen/GlobalISel/RegBankSelect.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/RegBankSelect.cpp
@@ -575,10 +575,11 @@
// Legalized property, so it should be.
// FIXME: This should be in the MachineVerifier, but it can't use the
// MachineLegalizer as it's currently in the separate GlobalISel library.
+ const MachineRegisterInfo &MRI = MF.getRegInfo();
if (const MachineLegalizer *MLI = MF.getSubtarget().getMachineLegalizer()) {
for (const MachineBasicBlock &MBB : MF) {
for (const MachineInstr &MI : MBB) {
- if (isPreISelGenericOpcode(MI.getOpcode()) && !MLI->isLegal(MI)) {
+ if (isPreISelGenericOpcode(MI.getOpcode()) && !MLI->isLegal(MI, MRI)) {
if (!TPC->isGlobalISelAbortEnabled()) {
MF.getProperties().set(
MachineFunctionProperties::Property::FailedISel);
diff --git a/llvm/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp b/llvm/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp
index 5a950ff1..7198526 100644
--- a/llvm/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp
@@ -367,7 +367,8 @@
// get the size of that register class.
RC = TRI.getMinimalPhysRegClass(Reg);
} else {
- unsigned RegSize = MRI.getSize(Reg);
+ LLT Ty = MRI.getType(Reg);
+ unsigned RegSize = Ty.isSized() ? Ty.getSizeInBits() : 0;
// If Reg is not a generic register, query the register class to
// get its size.
if (RegSize)
@@ -566,7 +567,7 @@
for (unsigned &NewVReg : NewVRegsForOpIdx) {
assert(PartMap != PartMapList.end() && "Out-of-bound access");
assert(NewVReg == 0 && "Register has already been created");
- NewVReg = MRI.createGenericVirtualRegister(PartMap->Length);
+ NewVReg = MRI.createGenericVirtualRegister(LLT::scalar(PartMap->Length));
MRI.setRegBank(NewVReg, *PartMap->RegBank);
++PartMap;
}
diff --git a/llvm/lib/CodeGen/MIRParser/MIParser.cpp b/llvm/lib/CodeGen/MIRParser/MIParser.cpp
index 91943ea..4dc964e 100644
--- a/llvm/lib/CodeGen/MIRParser/MIParser.cpp
+++ b/llvm/lib/CodeGen/MIRParser/MIParser.cpp
@@ -599,25 +599,6 @@
if (Token.isError() || parseInstruction(OpCode, Flags))
return true;
- SmallVector<LLT, 1> Tys;
- if (isPreISelGenericOpcode(OpCode)) {
- // For generic opcode, at least one type is mandatory.
- auto Loc = Token.location();
- bool ManyTypes = Token.is(MIToken::lbrace);
- if (ManyTypes)
- lex();
-
- // Now actually parse the type(s).
- do {
- Tys.resize(Tys.size() + 1);
- if (parseLowLevelType(Loc, Tys[Tys.size() - 1]))
- return true;
- } while (ManyTypes && consumeIfPresent(MIToken::comma));
-
- if (ManyTypes)
- expectAndConsume(MIToken::rbrace);
- }
-
// Parse the remaining machine operands.
while (!Token.isNewlineOrEOF() && Token.isNot(MIToken::kw_debug_location) &&
Token.isNot(MIToken::coloncolon) && Token.isNot(MIToken::lbrace)) {
@@ -673,10 +654,6 @@
// TODO: Check for extraneous machine operands.
MI = MF.CreateMachineInstr(MCID, DebugLocation, /*NoImplicit=*/true);
MI->setFlags(Flags);
- if (Tys.size() > 0) {
- for (unsigned i = 0; i < Tys.size(); ++i)
- MI->setType(Tys[i], i);
- }
for (const auto &Operand : Operands)
MI->addOperand(MF, Operand.Operand);
if (assignRegisterTies(*MI, Operands))
@@ -996,11 +973,14 @@
if (MRI.getRegClassOrRegBank(Reg).is<const TargetRegisterClass *>())
return error("unexpected size on non-generic virtual register");
- unsigned Size;
- if (parseSize(Size))
+ LLT Ty;
+ if (parseLowLevelType(Token.location(), Ty))
return true;
- MRI.setSize(Reg, Size);
+ if (expectAndConsume(MIToken::rparen))
+ return true;
+
+ MRI.setType(Reg, Ty);
} else if (PFS.GenericVRegs.count(Reg)) {
// Generic virtual registers must have a size.
// If we end up here this means the size hasn't been specified and
diff --git a/llvm/lib/CodeGen/MIRParser/MIRParser.cpp b/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
index 9a36405..e7fdcc0 100644
--- a/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
+++ b/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
@@ -415,7 +415,7 @@
if (StringRef(VReg.Class.Value).equals("_")) {
// This is a generic virtual register.
// The size will be set appropriately when we reach the definition.
- Reg = RegInfo.createGenericVirtualRegister(/*Size*/ 1);
+ Reg = RegInfo.createGenericVirtualRegister(LLT::scalar(1));
PFS.GenericVRegs.insert(Reg);
} else {
const auto *RC = getRegClass(MF, VReg.Class.Value);
@@ -428,7 +428,7 @@
VReg.Class.SourceRange.Start,
Twine("use of undefined register class or register bank '") +
VReg.Class.Value + "'");
- Reg = RegInfo.createGenericVirtualRegister(/*Size*/ 1);
+ Reg = RegInfo.createGenericVirtualRegister(LLT::scalar(1));
RegInfo.setRegBank(Reg, *RegBank);
PFS.GenericVRegs.insert(Reg);
}
diff --git a/llvm/lib/CodeGen/MIRPrinter.cpp b/llvm/lib/CodeGen/MIRPrinter.cpp
index 7b9baa7..b981f59 100644
--- a/llvm/lib/CodeGen/MIRPrinter.cpp
+++ b/llvm/lib/CodeGen/MIRPrinter.cpp
@@ -223,7 +223,8 @@
VReg.Class = StringRef(RegInfo.getRegBankOrNull(Reg)->getName()).lower();
else {
VReg.Class = std::string("_");
- assert(RegInfo.getSize(Reg) && "Generic registers must have a size");
+ assert(RegInfo.getType(Reg).isValid() &&
+ "Generic registers must have a valid type");
}
unsigned PreferredReg = RegInfo.getSimpleHint(Reg);
if (PreferredReg)
@@ -568,17 +569,6 @@
if (MI.getFlag(MachineInstr::FrameSetup))
OS << "frame-setup ";
OS << TII->getName(MI.getOpcode());
- if (isPreISelGenericOpcode(MI.getOpcode())) {
- assert(MI.getType().isValid() && "Generic instructions must have a type");
- unsigned NumTypes = MI.getNumTypes();
- OS << (NumTypes > 1 ? " {" : "") << ' ';
- for (unsigned i = 0; i < NumTypes; ++i) {
- MI.getType(i).print(OS);
- if (i + 1 != NumTypes)
- OS << ", ";
- }
- OS << (NumTypes > 1 ? " }" : "") << ' ';
- }
if (I < E)
OS << ' ';
@@ -787,8 +777,8 @@
if (ShouldPrintRegisterTies && Op.isTied() && !Op.isDef())
OS << "(tied-def " << Op.getParent()->findTiedOperandIdx(I) << ")";
assert((!IsDef || MRI) && "for IsDef, MRI must be provided");
- if (IsDef && MRI->getSize(Op.getReg()))
- OS << '(' << MRI->getSize(Op.getReg()) << ')';
+ if (IsDef && MRI->getType(Op.getReg()).isValid())
+ OS << '(' << MRI->getType(Op.getReg()) << ')';
break;
case MachineOperand::MO_Immediate:
OS << Op.getImm();
diff --git a/llvm/lib/CodeGen/MachineInstr.cpp b/llvm/lib/CodeGen/MachineInstr.cpp
index 5b1c39e..d79c32e9 100644
--- a/llvm/lib/CodeGen/MachineInstr.cpp
+++ b/llvm/lib/CodeGen/MachineInstr.cpp
@@ -680,12 +680,7 @@
DebugLoc dl, bool NoImp)
: MCID(&tid), Parent(nullptr), Operands(nullptr), NumOperands(0), Flags(0),
AsmPrinterFlags(0), NumMemRefs(0), MemRefs(nullptr),
- debugLoc(std::move(dl))
-#ifdef LLVM_BUILD_GLOBAL_ISEL
- ,
- Tys(0)
-#endif
-{
+ debugLoc(std::move(dl)) {
assert(debugLoc.hasTrivialDestructor() && "Expected trivial destructor");
// Reserve space for the expected number of operands.
@@ -704,12 +699,7 @@
MachineInstr::MachineInstr(MachineFunction &MF, const MachineInstr &MI)
: MCID(&MI.getDesc()), Parent(nullptr), Operands(nullptr), NumOperands(0),
Flags(0), AsmPrinterFlags(0), NumMemRefs(MI.NumMemRefs),
- MemRefs(MI.MemRefs), debugLoc(MI.getDebugLoc())
-#ifdef LLVM_BUILD_GLOBAL_ISEL
- ,
- Tys(0)
-#endif
-{
+ MemRefs(MI.MemRefs), debugLoc(MI.getDebugLoc()) {
assert(debugLoc.hasTrivialDestructor() && "Expected trivial destructor");
CapOperands = OperandCapacity::get(MI.getNumOperands());
@@ -732,37 +722,6 @@
return nullptr;
}
-// Implement dummy setter and getter for type when
-// global-isel is not built.
-// The proper implementation is WIP and is tracked here:
-// PR26576.
-#ifndef LLVM_BUILD_GLOBAL_ISEL
-unsigned MachineInstr::getNumTypes() const { return 0; }
-
-void MachineInstr::setType(LLT Ty, unsigned Idx) {}
-
-LLT MachineInstr::getType(unsigned Idx) const { return LLT{}; }
-
-void MachineInstr::removeTypes() {}
-
-#else
-unsigned MachineInstr::getNumTypes() const { return Tys.size(); }
-
-void MachineInstr::setType(LLT Ty, unsigned Idx) {
- assert((!Ty.isValid() || isPreISelGenericOpcode(getOpcode())) &&
- "Non generic instructions are not supposed to be typed");
- if (Tys.size() < Idx + 1)
- Tys.resize(Idx+1);
- Tys[Idx] = Ty;
-}
-
-LLT MachineInstr::getType(unsigned Idx) const { return Tys[Idx]; }
-
-void MachineInstr::removeTypes() {
- Tys.clear();
-}
-#endif // LLVM_BUILD_GLOBAL_ISEL
-
/// RemoveRegOperandsFromUseLists - Unlink all of the register operands in
/// this instruction from their respective use lists. This requires that the
/// operands already be on their use lists.
@@ -1751,9 +1710,9 @@
unsigned Reg = getOperand(StartOp).getReg();
if (TargetRegisterInfo::isVirtualRegister(Reg)) {
VirtRegs.push_back(Reg);
- unsigned Size;
- if (MRI && (Size = MRI->getSize(Reg)))
- OS << '(' << Size << ')';
+ LLT Ty = MRI ? MRI->getType(Reg) : LLT{};
+ if (Ty.isValid())
+ OS << '(' << Ty << ')';
}
}
@@ -1766,16 +1725,6 @@
else
OS << "UNKNOWN";
- if (getNumTypes() > 0) {
- OS << " { ";
- for (unsigned i = 0; i < getNumTypes(); ++i) {
- getType(i).print(OS);
- if (i + 1 != getNumTypes())
- OS << ", ";
- }
- OS << " } ";
- }
-
if (SkipOpers)
return;
diff --git a/llvm/lib/CodeGen/MachineRegisterInfo.cpp b/llvm/lib/CodeGen/MachineRegisterInfo.cpp
index 6e6c9f7..a16211c 100644
--- a/llvm/lib/CodeGen/MachineRegisterInfo.cpp
+++ b/llvm/lib/CodeGen/MachineRegisterInfo.cpp
@@ -112,47 +112,47 @@
return Reg;
}
-unsigned
-MachineRegisterInfo::getSize(unsigned VReg) const {
- VRegToSizeMap::const_iterator SizeIt = getVRegToSize().find(VReg);
- return SizeIt != getVRegToSize().end() ? SizeIt->second : 0;
+LLT MachineRegisterInfo::getType(unsigned VReg) const {
+ VRegToTypeMap::const_iterator TypeIt = getVRegToType().find(VReg);
+ return TypeIt != getVRegToType().end() ? TypeIt->second : LLT{};
}
-void MachineRegisterInfo::setSize(unsigned VReg, unsigned Size) {
+void MachineRegisterInfo::setType(unsigned VReg, LLT Ty) {
// Check that VReg doesn't have a class.
assert(!getRegClassOrRegBank(VReg).is<const TargetRegisterClass *>() &&
"Can't set the size of a non-generic virtual register");
- getVRegToSize()[VReg] = Size;
+ getVRegToType()[VReg] = Ty;
}
unsigned
-MachineRegisterInfo::createGenericVirtualRegister(unsigned Size) {
- assert(Size && "Cannot create empty virtual register");
+MachineRegisterInfo::createGenericVirtualRegister(LLT Ty) {
+ assert(Ty.isValid() && "Cannot create empty virtual register");
// New virtual register number.
unsigned Reg = TargetRegisterInfo::index2VirtReg(getNumVirtRegs());
VRegInfo.grow(Reg);
// FIXME: Should we use a dummy register bank?
VRegInfo[Reg].first = static_cast<RegisterBank *>(nullptr);
- getVRegToSize()[Reg] = Size;
+ getVRegToType()[Reg] = Ty;
RegAllocHints.grow(Reg);
if (TheDelegate)
TheDelegate->MRI_NoteNewVirtualRegister(Reg);
return Reg;
}
-void MachineRegisterInfo::clearVirtRegSizes() {
+void MachineRegisterInfo::clearVirtRegTypes() {
#ifndef NDEBUG
// Verify that the size of the now-constrained vreg is unchanged.
- for (auto &VRegToSize : getVRegToSize()) {
- auto *RC = getRegClass(VRegToSize.first);
- if (VRegToSize.second != (RC->getSize() * 8))
+ for (auto &VRegToType : getVRegToType()) {
+ auto *RC = getRegClass(VRegToType.first);
+ if (VRegToType.second.isSized() &&
+ VRegToType.second.getSizeInBits() > (RC->getSize() * 8))
llvm_unreachable(
"Virtual register has explicit size different from its class size");
}
#endif
- getVRegToSize().clear();
+ getVRegToType().clear();
}
/// clearVirtRegs - Remove all virtual registers (after physreg assignment).
diff --git a/llvm/lib/CodeGen/MachineVerifier.cpp b/llvm/lib/CodeGen/MachineVerifier.cpp
index 49620e7..f063942 100644
--- a/llvm/lib/CodeGen/MachineVerifier.cpp
+++ b/llvm/lib/CodeGen/MachineVerifier.cpp
@@ -887,16 +887,24 @@
}
// Check types.
- const unsigned NumTypes = MI->getNumTypes();
if (isPreISelGenericOpcode(MCID.getOpcode())) {
if (isFunctionSelected)
report("Unexpected generic instruction in a Selected function", MI);
- if (NumTypes == 0)
- report("Generic instruction must have a type", MI);
- } else {
- if (NumTypes != 0)
- report("Non-generic instruction cannot have a type", MI);
+ // Generic instructions specify equality constraints between some
+ // of their operands. Make sure these are consistent.
+ SmallVector<LLT, 4> Types;
+ for (unsigned i = 0; i < MCID.getNumOperands(); ++i) {
+ if (!MCID.OpInfo[i].isGenericType())
+ continue;
+ size_t TypeIdx = MCID.OpInfo[i].getGenericTypeIndex();
+ Types.resize(std::max(TypeIdx + 1, Types.size()));
+
+ LLT OpTy = MRI->getType(MI->getOperand(i).getReg());
+ if (Types[TypeIdx].isValid() && Types[TypeIdx] != OpTy)
+ report("type mismatch in generic instruction", MI);
+ Types[TypeIdx] = OpTy;
+ }
}
// Generic opcodes must not have physical register operands.
@@ -1026,9 +1034,10 @@
}
// The gvreg must have a size and it must not have a SubIdx.
- unsigned Size = MRI->getSize(Reg);
- if (!Size) {
- report("Generic virtual register must have a size", MO, MONum);
+ LLT Ty = MRI->getType(Reg);
+ if (!Ty.isValid()) {
+ report("Generic virtual register must have a valid type", MO,
+ MONum);
return;
}
@@ -1043,15 +1052,18 @@
}
// Make sure the register fits into its register bank if any.
- if (RegBank && RegBank->getSize() < Size) {
+ if (RegBank && Ty.isSized() &&
+ RegBank->getSize() < Ty.getSizeInBits()) {
report("Register bank is too small for virtual register", MO,
MONum);
errs() << "Register bank " << RegBank->getName() << " too small("
- << RegBank->getSize() << ") to fit " << Size << "-bits\n";
+ << RegBank->getSize() << ") to fit " << Ty.getSizeInBits()
+ << "-bits\n";
return;
}
if (SubIdx) {
- report("Generic virtual register does not subregister index", MO, MONum);
+ report("Generic virtual register does not subregister index", MO,
+ MONum);
return;
}
break;