diff options
Diffstat (limited to 'llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp')
-rw-r--r-- | llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp | 177 |
1 files changed, 74 insertions, 103 deletions
diff --git a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp index 67d9dacda61b..10f696d6a3b3 100644 --- a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp +++ b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp @@ -33,48 +33,10 @@ void MachineIRBuilder::setMF(MachineFunction &MF) { State.Observer = nullptr; } -void MachineIRBuilder::setMBB(MachineBasicBlock &MBB) { - State.MBB = &MBB; - State.II = MBB.end(); - assert(&getMF() == MBB.getParent() && - "Basic block is in a different function"); -} - -void MachineIRBuilder::setInstr(MachineInstr &MI) { - assert(MI.getParent() && "Instruction is not part of a basic block"); - setMBB(*MI.getParent()); - State.II = MI.getIterator(); -} - -void MachineIRBuilder::setCSEInfo(GISelCSEInfo *Info) { State.CSEInfo = Info; } - -void MachineIRBuilder::setInsertPt(MachineBasicBlock &MBB, - MachineBasicBlock::iterator II) { - assert(MBB.getParent() == &getMF() && - "Basic block is in a different function"); - State.MBB = &MBB; - State.II = II; -} - -void MachineIRBuilder::recordInsertion(MachineInstr *InsertedInstr) const { - if (State.Observer) - State.Observer->createdInstr(*InsertedInstr); -} - -void MachineIRBuilder::setChangeObserver(GISelChangeObserver &Observer) { - State.Observer = &Observer; -} - -void MachineIRBuilder::stopObservingChanges() { State.Observer = nullptr; } - //------------------------------------------------------------------------------ // Build instruction variants. //------------------------------------------------------------------------------ -MachineInstrBuilder MachineIRBuilder::buildInstr(unsigned Opcode) { - return insertInstr(buildInstrNoInsert(Opcode)); -} - MachineInstrBuilder MachineIRBuilder::buildInstrNoInsert(unsigned Opcode) { MachineInstrBuilder MIB = BuildMI(getMF(), getDL(), getTII().get(Opcode)); return MIB; @@ -107,13 +69,9 @@ MachineIRBuilder::buildIndirectDbgValue(Register Reg, const MDNode *Variable, assert( cast<DILocalVariable>(Variable)->isValidLocationForIntrinsic(getDL()) && "Expected inlined-at fields to agree"); - // DBG_VALUE insts now carry IR-level indirection in their DIExpression - // rather than encoding it in the instruction itself. - const DIExpression *DIExpr = cast<DIExpression>(Expr); - DIExpr = DIExpression::append(DIExpr, {dwarf::DW_OP_deref}); return insertInstr(BuildMI(getMF(), getDL(), getTII().get(TargetOpcode::DBG_VALUE), - /*IsIndirect*/ false, Reg, Variable, DIExpr)); + /*IsIndirect*/ true, Reg, Variable, Expr)); } MachineInstrBuilder MachineIRBuilder::buildFIDbgValue(int FI, @@ -124,15 +82,11 @@ MachineInstrBuilder MachineIRBuilder::buildFIDbgValue(int FI, assert( cast<DILocalVariable>(Variable)->isValidLocationForIntrinsic(getDL()) && "Expected inlined-at fields to agree"); - // DBG_VALUE insts now carry IR-level indirection in their DIExpression - // rather than encoding it in the instruction itself. - const DIExpression *DIExpr = cast<DIExpression>(Expr); - DIExpr = DIExpression::append(DIExpr, {dwarf::DW_OP_deref}); return buildInstr(TargetOpcode::DBG_VALUE) .addFrameIndex(FI) - .addReg(0) + .addImm(0) .addMetadata(Variable) - .addMetadata(DIExpr); + .addMetadata(Expr); } MachineInstrBuilder MachineIRBuilder::buildConstDbgValue(const Constant &C, @@ -143,7 +97,7 @@ MachineInstrBuilder MachineIRBuilder::buildConstDbgValue(const Constant &C, assert( cast<DILocalVariable>(Variable)->isValidLocationForIntrinsic(getDL()) && "Expected inlined-at fields to agree"); - auto MIB = buildInstr(TargetOpcode::DBG_VALUE); + auto MIB = buildInstrNoInsert(TargetOpcode::DBG_VALUE); if (auto *CI = dyn_cast<ConstantInt>(&C)) { if (CI->getBitWidth() > 64) MIB.addCImm(CI); @@ -156,7 +110,8 @@ MachineInstrBuilder MachineIRBuilder::buildConstDbgValue(const Constant &C, MIB.addReg(0U); } - return MIB.addReg(0).addMetadata(Variable).addMetadata(Expr); + MIB.addImm(0).addMetadata(Variable).addMetadata(Expr); + return insertInstr(MIB); } MachineInstrBuilder MachineIRBuilder::buildDbgLabel(const MDNode *Label) { @@ -170,12 +125,12 @@ MachineInstrBuilder MachineIRBuilder::buildDbgLabel(const MDNode *Label) { MachineInstrBuilder MachineIRBuilder::buildDynStackAlloc(const DstOp &Res, const SrcOp &Size, - unsigned Align) { + Align Alignment) { assert(Res.getLLTTy(*getMRI()).isPointer() && "expected ptr dst type"); auto MIB = buildInstr(TargetOpcode::G_DYN_STACKALLOC); Res.addDefToMIB(*getMRI(), MIB); Size.addSrcToMIB(MIB); - MIB.addImm(Align); + MIB.addImm(Alignment.value()); return MIB; } @@ -207,14 +162,14 @@ MachineInstrBuilder MachineIRBuilder::buildJumpTable(const LLT PtrTy, .addJumpTableIndex(JTI); } -void MachineIRBuilder::validateBinaryOp(const LLT &Res, const LLT &Op0, - const LLT &Op1) { +void MachineIRBuilder::validateBinaryOp(const LLT Res, const LLT Op0, + const LLT Op1) { assert((Res.isScalar() || Res.isVector()) && "invalid operand type"); assert((Res == Op0 && Res == Op1) && "type mismatch"); } -void MachineIRBuilder::validateShiftOp(const LLT &Res, const LLT &Op0, - const LLT &Op1) { +void MachineIRBuilder::validateShiftOp(const LLT Res, const LLT Op0, + const LLT Op1) { assert((Res.isScalar() || Res.isVector()) && "invalid operand type"); assert((Res == Op0) && "type mismatch"); } @@ -222,16 +177,16 @@ void MachineIRBuilder::validateShiftOp(const LLT &Res, const LLT &Op0, MachineInstrBuilder MachineIRBuilder::buildPtrAdd(const DstOp &Res, const SrcOp &Op0, const SrcOp &Op1) { - assert(Res.getLLTTy(*getMRI()).isPointer() && + assert(Res.getLLTTy(*getMRI()).getScalarType().isPointer() && Res.getLLTTy(*getMRI()) == Op0.getLLTTy(*getMRI()) && "type mismatch"); - assert(Op1.getLLTTy(*getMRI()).isScalar() && "invalid offset type"); + assert(Op1.getLLTTy(*getMRI()).getScalarType().isScalar() && "invalid offset type"); return buildInstr(TargetOpcode::G_PTR_ADD, {Res}, {Op0, Op1}); } Optional<MachineInstrBuilder> MachineIRBuilder::materializePtrAdd(Register &Res, Register Op0, - const LLT &ValueTy, uint64_t Value) { + const LLT ValueTy, uint64_t Value) { assert(Res == 0 && "Res is a result argument"); assert(ValueTy.isScalar() && "invalid offset type"); @@ -245,17 +200,14 @@ MachineIRBuilder::materializePtrAdd(Register &Res, Register Op0, return buildPtrAdd(Res, Op0, Cst.getReg(0)); } -MachineInstrBuilder MachineIRBuilder::buildPtrMask(const DstOp &Res, - const SrcOp &Op0, - uint32_t NumBits) { - assert(Res.getLLTTy(*getMRI()).isPointer() && - Res.getLLTTy(*getMRI()) == Op0.getLLTTy(*getMRI()) && "type mismatch"); - - auto MIB = buildInstr(TargetOpcode::G_PTR_MASK); - Res.addDefToMIB(*getMRI(), MIB); - Op0.addSrcToMIB(MIB); - MIB.addImm(NumBits); - return MIB; +MachineInstrBuilder MachineIRBuilder::buildMaskLowPtrBits(const DstOp &Res, + const SrcOp &Op0, + uint32_t NumBits) { + LLT PtrTy = Res.getLLTTy(*getMRI()); + LLT MaskTy = LLT::scalar(PtrTy.getSizeInBits()); + Register MaskReg = getMRI()->createGenericVirtualRegister(MaskTy); + buildConstant(MaskReg, maskTrailingZeros<uint64_t>(NumBits)); + return buildPtrMask(Res, Op0, MaskReg); } MachineInstrBuilder MachineIRBuilder::buildBr(MachineBasicBlock &Dest) { @@ -298,6 +250,7 @@ MachineInstrBuilder MachineIRBuilder::buildConstant(const DstOp &Res, } auto Const = buildInstr(TargetOpcode::G_CONSTANT); + Const->setDebugLoc(DebugLoc()); Res.addDefToMIB(*getMRI(), Const); Const.addCImm(&Val); return Const; @@ -331,6 +284,7 @@ MachineInstrBuilder MachineIRBuilder::buildFConstant(const DstOp &Res, } auto Const = buildInstr(TargetOpcode::G_FCONSTANT); + Const->setDebugLoc(DebugLoc()); Res.addDefToMIB(*getMRI(), Const); Const.addFPImm(&Val); return Const; @@ -385,6 +339,23 @@ MachineInstrBuilder MachineIRBuilder::buildLoadInstr(unsigned Opcode, return MIB; } +MachineInstrBuilder MachineIRBuilder::buildLoadFromOffset( + const DstOp &Dst, const SrcOp &BasePtr, + MachineMemOperand &BaseMMO, int64_t Offset) { + LLT LoadTy = Dst.getLLTTy(*getMRI()); + MachineMemOperand *OffsetMMO = + getMF().getMachineMemOperand(&BaseMMO, Offset, LoadTy.getSizeInBytes()); + + if (Offset == 0) // This may be a size or type changing load. + return buildLoad(Dst, BasePtr, *OffsetMMO); + + LLT PtrTy = BasePtr.getLLTTy(*getMRI()); + LLT OffsetTy = LLT::scalar(PtrTy.getSizeInBits()); + auto ConstOffset = buildConstant(OffsetTy, Offset); + auto Ptr = buildPtrAdd(PtrTy, BasePtr, ConstOffset); + return buildLoad(Dst, Ptr, *OffsetMMO); +} + MachineInstrBuilder MachineIRBuilder::buildStore(const SrcOp &Val, const SrcOp &Addr, MachineMemOperand &MMO) { @@ -398,22 +369,6 @@ MachineInstrBuilder MachineIRBuilder::buildStore(const SrcOp &Val, return MIB; } -MachineInstrBuilder MachineIRBuilder::buildUAddo(const DstOp &Res, - const DstOp &CarryOut, - const SrcOp &Op0, - const SrcOp &Op1) { - return buildInstr(TargetOpcode::G_UADDO, {Res, CarryOut}, {Op0, Op1}); -} - -MachineInstrBuilder MachineIRBuilder::buildUAdde(const DstOp &Res, - const DstOp &CarryOut, - const SrcOp &Op0, - const SrcOp &Op1, - const SrcOp &CarryIn) { - return buildInstr(TargetOpcode::G_UADDE, {Res, CarryOut}, - {Op0, Op1, CarryIn}); -} - MachineInstrBuilder MachineIRBuilder::buildAnyExt(const DstOp &Res, const SrcOp &Op) { return buildInstr(TargetOpcode::G_ANYEXT, Res, Op); @@ -537,7 +492,7 @@ void MachineIRBuilder::buildSequence(Register Res, ArrayRef<Register> Ops, #ifndef NDEBUG assert(Ops.size() == Indices.size() && "incompatible args"); assert(!Ops.empty() && "invalid trivial sequence"); - assert(std::is_sorted(Indices.begin(), Indices.end()) && + assert(llvm::is_sorted(Indices) && "sequence offsets must be in ascending order"); assert(getMRI()->getType(Res).isValid() && "invalid operand type"); @@ -587,6 +542,13 @@ MachineInstrBuilder MachineIRBuilder::buildMerge(const DstOp &Res, return buildInstr(TargetOpcode::G_MERGE_VALUES, Res, TmpVec); } +MachineInstrBuilder +MachineIRBuilder::buildMerge(const DstOp &Res, + std::initializer_list<SrcOp> Ops) { + assert(Ops.size() > 1); + return buildInstr(TargetOpcode::G_MERGE_VALUES, Res, Ops); +} + MachineInstrBuilder MachineIRBuilder::buildUnmerge(ArrayRef<LLT> Res, const SrcOp &Op) { // Unfortunately to convert from ArrayRef<LLT> to ArrayRef<DstOp>, @@ -650,22 +612,20 @@ MachineIRBuilder::buildConcatVectors(const DstOp &Res, ArrayRef<Register> Ops) { return buildInstr(TargetOpcode::G_CONCAT_VECTORS, Res, TmpVec); } -MachineInstrBuilder MachineIRBuilder::buildInsert(Register Res, Register Src, - Register Op, unsigned Index) { - assert(Index + getMRI()->getType(Op).getSizeInBits() <= - getMRI()->getType(Res).getSizeInBits() && +MachineInstrBuilder MachineIRBuilder::buildInsert(const DstOp &Res, + const SrcOp &Src, + const SrcOp &Op, + unsigned Index) { + assert(Index + Op.getLLTTy(*getMRI()).getSizeInBits() <= + Res.getLLTTy(*getMRI()).getSizeInBits() && "insertion past the end of a register"); - if (getMRI()->getType(Res).getSizeInBits() == - getMRI()->getType(Op).getSizeInBits()) { + if (Res.getLLTTy(*getMRI()).getSizeInBits() == + Op.getLLTTy(*getMRI()).getSizeInBits()) { return buildCast(Res, Op); } - return buildInstr(TargetOpcode::G_INSERT) - .addDef(Res) - .addUse(Src) - .addUse(Op) - .addImm(Index); + return buildInstr(TargetOpcode::G_INSERT, Res, {Src, Op, uint64_t(Index)}); } MachineInstrBuilder MachineIRBuilder::buildIntrinsic(Intrinsic::ID ID, @@ -915,7 +875,7 @@ MachineIRBuilder::buildBlockAddress(Register Res, const BlockAddress *BA) { return buildInstr(TargetOpcode::G_BLOCK_ADDR).addDef(Res).addBlockAddress(BA); } -void MachineIRBuilder::validateTruncExt(const LLT &DstTy, const LLT &SrcTy, +void MachineIRBuilder::validateTruncExt(const LLT DstTy, const LLT SrcTy, bool IsExtend) { #ifndef NDEBUG if (DstTy.isVector()) { @@ -934,8 +894,8 @@ void MachineIRBuilder::validateTruncExt(const LLT &DstTy, const LLT &SrcTy, #endif } -void MachineIRBuilder::validateSelectOp(const LLT &ResTy, const LLT &TstTy, - const LLT &Op0Ty, const LLT &Op1Ty) { +void MachineIRBuilder::validateSelectOp(const LLT ResTy, const LLT TstTy, + const LLT Op0Ty, const LLT Op1Ty) { #ifndef NDEBUG assert((ResTy.isScalar() || ResTy.isVector() || ResTy.isPointer()) && "invalid operand type"); @@ -978,7 +938,11 @@ MachineInstrBuilder MachineIRBuilder::buildInstr(unsigned Opc, case TargetOpcode::G_SMIN: case TargetOpcode::G_SMAX: case TargetOpcode::G_UMIN: - case TargetOpcode::G_UMAX: { + case TargetOpcode::G_UMAX: + case TargetOpcode::G_UADDSAT: + case TargetOpcode::G_SADDSAT: + case TargetOpcode::G_USUBSAT: + case TargetOpcode::G_SSUBSAT: { // All these are binary ops. assert(DstOps.size() == 1 && "Invalid Dst"); assert(SrcOps.size() == 2 && "Invalid Srcs"); @@ -1013,6 +977,13 @@ MachineInstrBuilder MachineIRBuilder::buildInstr(unsigned Opc, SrcOps[0].getLLTTy(*getMRI()), false); break; } + case TargetOpcode::G_BITCAST: { + assert(DstOps.size() == 1 && "Invalid Dst"); + assert(SrcOps.size() == 1 && "Invalid Srcs"); + assert(DstOps[0].getLLTTy(*getMRI()).getSizeInBits() == + SrcOps[0].getLLTTy(*getMRI()).getSizeInBits() && "invalid bitcast"); + break; + } case TargetOpcode::COPY: assert(DstOps.size() == 1 && "Invalid Dst"); // If the caller wants to add a subreg source it has to be done separately |