diff options
Diffstat (limited to 'llvm/lib/CodeGen/CodeGenPrepare.cpp')
-rw-r--r-- | llvm/lib/CodeGen/CodeGenPrepare.cpp | 221 |
1 files changed, 151 insertions, 70 deletions
diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp index 07dc718..885d2d3 100644 --- a/llvm/lib/CodeGen/CodeGenPrepare.cpp +++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp @@ -459,6 +459,7 @@ private: bool optimizeExtractElementInst(Instruction *Inst); bool dupRetToEnableTailCallOpts(BasicBlock *BB, ModifyDT &ModifiedDT); bool fixupDbgValue(Instruction *I); + bool fixupDPValue(DPValue &I); bool placeDbgValues(Function &F); bool placePseudoProbes(Function &F); bool canFormExtLd(const SmallVectorImpl<Instruction *> &MovedExts, @@ -1753,8 +1754,8 @@ static bool sinkCmpExpression(CmpInst *Cmp, const TargetLowering &TLI) { BasicBlock::iterator InsertPt = UserBB->getFirstInsertionPt(); assert(InsertPt != UserBB->end()); InsertedCmp = CmpInst::Create(Cmp->getOpcode(), Cmp->getPredicate(), - Cmp->getOperand(0), Cmp->getOperand(1), "", - &*InsertPt); + Cmp->getOperand(0), Cmp->getOperand(1), ""); + InsertedCmp->insertBefore(*UserBB, InsertPt); // Propagate the debug info. InsertedCmp->setDebugLoc(Cmp->getDebugLoc()); } @@ -2066,10 +2067,13 @@ SinkShiftAndTruncate(BinaryOperator *ShiftI, Instruction *User, ConstantInt *CI, // Sink the trunc BasicBlock::iterator TruncInsertPt = TruncUserBB->getFirstInsertionPt(); TruncInsertPt++; + // It will go ahead of any debug-info. + TruncInsertPt.setHeadBit(true); assert(TruncInsertPt != TruncUserBB->end()); InsertedTrunc = CastInst::Create(TruncI->getOpcode(), InsertedShift, - TruncI->getType(), "", &*TruncInsertPt); + TruncI->getType(), ""); + InsertedTrunc->insertBefore(*TruncUserBB, TruncInsertPt); InsertedTrunc->setDebugLoc(TruncI->getDebugLoc()); MadeChange = true; @@ -2234,7 +2238,9 @@ static bool despeculateCountZeros(IntrinsicInst *CountZeros, // Create another block after the count zero intrinsic. A PHI will be added // in this block to select the result of the intrinsic or the bit-width // constant if the input to the intrinsic is zero. - BasicBlock::iterator SplitPt = ++(BasicBlock::iterator(CountZeros)); + BasicBlock::iterator SplitPt = std::next(BasicBlock::iterator(CountZeros)); + // Any debug-info after CountZeros should not be included. + SplitPt.setHeadBit(true); BasicBlock *EndBlock = CallBlock->splitBasicBlock(SplitPt, "cond.end"); if (IsHugeFunc) FreshBBs.insert(EndBlock); @@ -2829,6 +2835,7 @@ class TypePromotionTransaction { Instruction *PrevInst; BasicBlock *BB; } Point; + std::optional<DPValue::self_iterator> BeforeDPValue = std::nullopt; /// Remember whether or not the instruction had a previous instruction. bool HasPrevInstruction; @@ -2836,12 +2843,19 @@ class TypePromotionTransaction { public: /// Record the position of \p Inst. InsertionHandler(Instruction *Inst) { - BasicBlock::iterator It = Inst->getIterator(); - HasPrevInstruction = (It != (Inst->getParent()->begin())); - if (HasPrevInstruction) - Point.PrevInst = &*--It; - else - Point.BB = Inst->getParent(); + HasPrevInstruction = (Inst != &*(Inst->getParent()->begin())); + BasicBlock *BB = Inst->getParent(); + + // Record where we would have to re-insert the instruction in the sequence + // of DPValues, if we ended up reinserting. + if (BB->IsNewDbgInfoFormat) + BeforeDPValue = Inst->getDbgReinsertionPosition(); + + if (HasPrevInstruction) { + Point.PrevInst = &*std::prev(Inst->getIterator()); + } else { + Point.BB = BB; + } } /// Insert \p Inst at the recorded position. @@ -2849,14 +2863,16 @@ class TypePromotionTransaction { if (HasPrevInstruction) { if (Inst->getParent()) Inst->removeFromParent(); - Inst->insertAfter(Point.PrevInst); + Inst->insertAfter(&*Point.PrevInst); } else { - Instruction *Position = &*Point.BB->getFirstInsertionPt(); + BasicBlock::iterator Position = Point.BB->getFirstInsertionPt(); if (Inst->getParent()) - Inst->moveBefore(Position); + Inst->moveBefore(*Point.BB, Position); else - Inst->insertBefore(Position); + Inst->insertBefore(*Point.BB, Position); } + + Inst->getParent()->reinsertInstInDPValues(Inst, BeforeDPValue); } }; @@ -3059,6 +3075,8 @@ class TypePromotionTransaction { SmallVector<InstructionAndIdx, 4> OriginalUses; /// Keep track of the debug users. SmallVector<DbgValueInst *, 1> DbgValues; + /// And non-instruction debug-users too. + SmallVector<DPValue *, 1> DPValues; /// Keep track of the new value so that we can undo it by replacing /// instances of the new value with the original value. @@ -3079,7 +3097,7 @@ class TypePromotionTransaction { } // Record the debug uses separately. They are not in the instruction's // use list, but they are replaced by RAUW. - findDbgValues(DbgValues, Inst); + findDbgValues(DbgValues, Inst, &DPValues); // Now, we can replace the uses. Inst->replaceAllUsesWith(New); @@ -3096,6 +3114,10 @@ class TypePromotionTransaction { // correctness and utility of debug value instructions. for (auto *DVI : DbgValues) DVI->replaceVariableLocationOp(New, Inst); + // Similar story with DPValues, the non-instruction representation of + // dbg.values. + for (DPValue *DPV : DPValues) // tested by transaction-test I'm adding + DPV->replaceVariableLocationOp(New, Inst); } }; @@ -6749,7 +6771,7 @@ bool CodeGenPrepare::optimizeLoadExt(LoadInst *Load) { !TLI->isLoadExtLegal(ISD::ZEXTLOAD, LoadResultVT, TruncVT)) return false; - IRBuilder<> Builder(Load->getNextNode()); + IRBuilder<> Builder(Load->getNextNonDebugInstruction()); auto *NewAnd = cast<Instruction>( Builder.CreateAnd(Load, ConstantInt::get(Ctx, DemandBits))); // Mark this instruction as "inserted by CGP", so that other @@ -7005,7 +7027,9 @@ bool CodeGenPrepare::optimizeSelectInst(SelectInst *SI) { // Split the select block, according to how many (if any) values go on each // side. BasicBlock *StartBlock = SI->getParent(); - BasicBlock::iterator SplitPt = ++(BasicBlock::iterator(LastSI)); + BasicBlock::iterator SplitPt = std::next(BasicBlock::iterator(LastSI)); + // We should split before any debug-info. + SplitPt.setHeadBit(true); IRBuilder<> IB(SI); auto *CondFr = IB.CreateFreeze(SI->getCondition(), SI->getName() + ".frozen"); @@ -7017,18 +7041,18 @@ bool CodeGenPrepare::optimizeSelectInst(SelectInst *SI) { BranchInst *FalseBranch = nullptr; if (TrueInstrs.size() == 0) { FalseBranch = cast<BranchInst>(SplitBlockAndInsertIfElse( - CondFr, &*SplitPt, false, nullptr, nullptr, LI)); + CondFr, SplitPt, false, nullptr, nullptr, LI)); FalseBlock = FalseBranch->getParent(); EndBlock = cast<BasicBlock>(FalseBranch->getOperand(0)); } else if (FalseInstrs.size() == 0) { TrueBranch = cast<BranchInst>(SplitBlockAndInsertIfThen( - CondFr, &*SplitPt, false, nullptr, nullptr, LI)); + CondFr, SplitPt, false, nullptr, nullptr, LI)); TrueBlock = TrueBranch->getParent(); EndBlock = cast<BasicBlock>(TrueBranch->getOperand(0)); } else { Instruction *ThenTerm = nullptr; Instruction *ElseTerm = nullptr; - SplitBlockAndInsertIfThenElse(CondFr, &*SplitPt, &ThenTerm, &ElseTerm, + SplitBlockAndInsertIfThenElse(CondFr, SplitPt, &ThenTerm, &ElseTerm, nullptr, nullptr, LI); TrueBranch = cast<BranchInst>(ThenTerm); FalseBranch = cast<BranchInst>(ElseTerm); @@ -8095,10 +8119,14 @@ static bool optimizeBranch(BranchInst *Branch, const TargetLowering &TLI, } bool CodeGenPrepare::optimizeInst(Instruction *I, ModifyDT &ModifiedDT) { + bool AnyChange = false; + for (DPValue &DPV : I->getDbgValueRange()) + AnyChange |= fixupDPValue(DPV); + // Bail out if we inserted the instruction to prevent optimizations from // stepping on each other's toes. if (InsertedInsts.count(I)) - return false; + return AnyChange; // TODO: Move into the switch on opcode below here. if (PHINode *P = dyn_cast<PHINode>(I)) { @@ -8112,7 +8140,7 @@ bool CodeGenPrepare::optimizeInst(Instruction *I, ModifyDT &ModifiedDT) { ++NumPHIsElim; return true; } - return false; + return AnyChange; } if (CastInst *CI = dyn_cast<CastInst>(I)) { @@ -8123,7 +8151,7 @@ bool CodeGenPrepare::optimizeInst(Instruction *I, ModifyDT &ModifiedDT) { // the address of globals out of a loop). If this is the case, we don't // want to forward-subst the cast. if (isa<Constant>(CI->getOperand(0))) - return false; + return AnyChange; if (OptimizeNoopCopyExpression(CI, *TLI, *DL)) return true; @@ -8149,7 +8177,7 @@ bool CodeGenPrepare::optimizeInst(Instruction *I, ModifyDT &ModifiedDT) { return MadeChange | optimizeExtUses(I); } } - return false; + return AnyChange; } if (auto *Cmp = dyn_cast<CmpInst>(I)) @@ -8244,7 +8272,7 @@ bool CodeGenPrepare::optimizeInst(Instruction *I, ModifyDT &ModifiedDT) { return true; } } - return false; + return AnyChange; } if (tryToSinkFreeOperands(I)) @@ -8269,7 +8297,7 @@ bool CodeGenPrepare::optimizeInst(Instruction *I, ModifyDT &ModifiedDT) { return optimizeBranch(cast<BranchInst>(I), *TLI, FreshBBs, IsHugeFunc); } - return false; + return AnyChange; } /// Given an OR instruction, check to see if this is a bitreverse @@ -8359,6 +8387,49 @@ bool CodeGenPrepare::fixupDbgValue(Instruction *I) { return AnyChange; } +// FIXME: should updating debug-info really cause the "changed" flag to fire, +// which can cause a function to be reprocessed? +bool CodeGenPrepare::fixupDPValue(DPValue &DPV) { + if (DPV.Type != DPValue::LocationType::Value) + return false; + + // Does this DPValue refer to a sunk address calculation? + bool AnyChange = false; + SmallDenseSet<Value *> LocationOps(DPV.location_ops().begin(), + DPV.location_ops().end()); + for (Value *Location : LocationOps) { + WeakTrackingVH SunkAddrVH = SunkAddrs[Location]; + Value *SunkAddr = SunkAddrVH.pointsToAliveValue() ? SunkAddrVH : nullptr; + if (SunkAddr) { + // Point dbg.value at locally computed address, which should give the best + // opportunity to be accurately lowered. This update may change the type + // of pointer being referred to; however this makes no difference to + // debugging information, and we can't generate bitcasts that may affect + // codegen. + DPV.replaceVariableLocationOp(Location, SunkAddr); + AnyChange = true; + } + } + return AnyChange; +} + +static void DbgInserterHelper(DbgValueInst *DVI, Instruction *VI) { + DVI->removeFromParent(); + if (isa<PHINode>(VI)) + DVI->insertBefore(&*VI->getParent()->getFirstInsertionPt()); + else + DVI->insertAfter(VI); +} + +static void DbgInserterHelper(DPValue *DPV, Instruction *VI) { + DPV->removeFromParent(); + BasicBlock *VIBB = VI->getParent(); + if (isa<PHINode>(VI)) + VIBB->insertDPValueBefore(DPV, VIBB->getFirstInsertionPt()); + else + VIBB->insertDPValueAfter(DPV, VI); +} + // A llvm.dbg.value may be using a value before its definition, due to // optimizations in this pass and others. Scan for such dbg.values, and rescue // them by moving the dbg.value to immediately after the value definition. @@ -8368,59 +8439,69 @@ bool CodeGenPrepare::placeDbgValues(Function &F) { bool MadeChange = false; DominatorTree DT(F); - for (BasicBlock &BB : F) { - for (Instruction &Insn : llvm::make_early_inc_range(BB)) { - DbgValueInst *DVI = dyn_cast<DbgValueInst>(&Insn); - if (!DVI) + auto DbgProcessor = [&](auto *DbgItem, Instruction *Position) { + SmallVector<Instruction *, 4> VIs; + for (Value *V : DbgItem->location_ops()) + if (Instruction *VI = dyn_cast_or_null<Instruction>(V)) + VIs.push_back(VI); + + // This item may depend on multiple instructions, complicating any + // potential sink. This block takes the defensive approach, opting to + // "undef" the item if it has more than one instruction and any of them do + // not dominate iem. + for (Instruction *VI : VIs) { + if (VI->isTerminator()) continue; - SmallVector<Instruction *, 4> VIs; - for (Value *V : DVI->getValues()) - if (Instruction *VI = dyn_cast_or_null<Instruction>(V)) - VIs.push_back(VI); - - // This DVI may depend on multiple instructions, complicating any - // potential sink. This block takes the defensive approach, opting to - // "undef" the DVI if it has more than one instruction and any of them do - // not dominate DVI. - for (Instruction *VI : VIs) { - if (VI->isTerminator()) - continue; + // If VI is a phi in a block with an EHPad terminator, we can't insert + // after it. + if (isa<PHINode>(VI) && VI->getParent()->getTerminator()->isEHPad()) + continue; - // If VI is a phi in a block with an EHPad terminator, we can't insert - // after it. - if (isa<PHINode>(VI) && VI->getParent()->getTerminator()->isEHPad()) - continue; + // If the defining instruction dominates the dbg.value, we do not need + // to move the dbg.value. + if (DT.dominates(VI, Position)) + continue; - // If the defining instruction dominates the dbg.value, we do not need - // to move the dbg.value. - if (DT.dominates(VI, DVI)) - continue; + // If we depend on multiple instructions and any of them doesn't + // dominate this DVI, we probably can't salvage it: moving it to + // after any of the instructions could cause us to lose the others. + if (VIs.size() > 1) { + LLVM_DEBUG( + dbgs() + << "Unable to find valid location for Debug Value, undefing:\n" + << *DbgItem); + DbgItem->setKillLocation(); + break; + } - // If we depend on multiple instructions and any of them doesn't - // dominate this DVI, we probably can't salvage it: moving it to - // after any of the instructions could cause us to lose the others. - if (VIs.size() > 1) { - LLVM_DEBUG( - dbgs() - << "Unable to find valid location for Debug Value, undefing:\n" - << *DVI); - DVI->setKillLocation(); - break; - } + LLVM_DEBUG(dbgs() << "Moving Debug Value before :\n" + << *DbgItem << ' ' << *VI); + DbgInserterHelper(DbgItem, VI); + MadeChange = true; + ++NumDbgValueMoved; + } + }; - LLVM_DEBUG(dbgs() << "Moving Debug Value before :\n" - << *DVI << ' ' << *VI); - DVI->removeFromParent(); - if (isa<PHINode>(VI)) - DVI->insertBefore(&*VI->getParent()->getFirstInsertionPt()); - else - DVI->insertAfter(VI); - MadeChange = true; - ++NumDbgValueMoved; + for (BasicBlock &BB : F) { + for (Instruction &Insn : llvm::make_early_inc_range(BB)) { + // Process dbg.value intrinsics. + DbgValueInst *DVI = dyn_cast<DbgValueInst>(&Insn); + if (DVI) { + DbgProcessor(DVI, DVI); + continue; + } + + // If this isn't a dbg.value, process any attached DPValue records + // attached to this instruction. + for (DPValue &DPV : llvm::make_early_inc_range(Insn.getDbgValueRange())) { + if (DPV.Type != DPValue::LocationType::Value) + continue; + DbgProcessor(&DPV, &Insn); } } } + return MadeChange; } |