diff --git a/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h b/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h --- a/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h @@ -121,14 +121,41 @@ MachineInstrBuilder SrcMIB; unsigned Reg; CmpInst::Predicate Pred; + APInt Imm; }; public: - enum class SrcType { Ty_Reg, Ty_MIB, Ty_Predicate }; + enum class SrcType { Ty_Reg, Ty_MIB, Ty_Predicate, Ty_Imm }; SrcOp(unsigned R) : Reg(R), Ty(SrcType::Ty_Reg) {} SrcOp(const MachineOperand &Op) : Reg(Op.getReg()), Ty(SrcType::Ty_Reg) {} SrcOp(const MachineInstrBuilder &MIB) : SrcMIB(MIB), Ty(SrcType::Ty_MIB) {} SrcOp(const CmpInst::Predicate P) : Pred(P), Ty(SrcType::Ty_Predicate) {} + SrcOp(const APInt &V) : Imm(V), Ty(SrcType::Ty_Imm) {} + SrcOp(const SrcOp &Other) { + // copy-and-swap is apparently preferred but doesn't actually help me reduce + // the code duplication in this case as the swap ends up requiring the + // duplicate code instead; + operator=(Other); + } + ~SrcOp() {} + SrcOp& operator=(const SrcOp &Other) { + Ty = Other.Ty; + switch (Ty) { + case SrcType::Ty_Predicate: + Pred = Other.Pred; + break; + case SrcType::Ty_Reg: + Reg = Other.Reg; + break; + case SrcType::Ty_MIB: + SrcMIB = Other.SrcMIB; + break; + case SrcType::Ty_Imm: + Imm = Other.Imm; + break; + } + return *this; + } void addSrcToMIB(MachineInstrBuilder &MIB) const { switch (Ty) { @@ -141,12 +168,16 @@ case SrcType::Ty_MIB: MIB.addUse(SrcMIB->getOperand(0).getReg()); break; + case SrcType::Ty_Imm: + MIB.addImm(Imm.getSExtValue()); + break; } } LLT getLLTTy(const MachineRegisterInfo &MRI) const { switch (Ty) { case SrcType::Ty_Predicate: + case SrcType::Ty_Imm: llvm_unreachable("Not a register operand"); case SrcType::Ty_Reg: return MRI.getType(Reg); @@ -159,6 +190,7 @@ unsigned getReg() const { switch (Ty) { case SrcType::Ty_Predicate: + case SrcType::Ty_Imm: llvm_unreachable("Not a register operand"); case SrcType::Ty_Reg: return Reg; @@ -177,6 +209,15 @@ } } + APInt getImm() const { + switch (Ty) { + case SrcType::Ty_Imm: + return Imm; + default: + llvm_unreachable("Not an immediate"); + } + } + SrcType getSrcOpKind() const { return Ty; } private: