[IR][NFCI] Remove *WithoutDebug (#187240)

The function instructionsWithoutDebug serves two uses: skipping debug
intrinsics and skipping pseudo instructions. Nonetheless, these
functions are expensive due to out-of-line filtering using
std::function. Ideally, the filter should be inlined, but that would
require including IntrinsicInst.h in BasicBlock.h.

We no longer use debug intrinsics, so the first use (parameter false) is
no longer needed. The second use is sometimes needed, but the
distinction between PseudoProbe instructions can be made at the call
sites more easily in many cases.

Therefore, remove instructionsWithoutDebug/sizeWithoutDebug.

c-t-t stage2-O3 -0.21%.
This commit is contained in:
Alexis Engelke 2026-03-18 16:08:41 +01:00 committed by GitHub
parent 9f4a1ebb20
commit 080bc25728
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
30 changed files with 71 additions and 158 deletions

View file

@ -363,27 +363,6 @@ public:
static_cast<const BasicBlock *>(this)->getFirstMayFaultInst());
}
/// Return a const iterator range over the instructions in the block, skipping
/// any debug instructions. Skip any pseudo operations as well if \c
/// SkipPseudoOp is true.
LLVM_ABI
iterator_range<filter_iterator<BasicBlock::const_iterator,
std::function<bool(const Instruction &)>>>
instructionsWithoutDebug(bool SkipPseudoOp = true) const;
/// Return an iterator range over the instructions in the block, skipping any
/// debug instructions. Skip and any pseudo operations as well if \c
/// SkipPseudoOp is true.
LLVM_ABI iterator_range<
filter_iterator<BasicBlock::iterator, std::function<bool(Instruction &)>>>
instructionsWithoutDebug(bool SkipPseudoOp = true);
/// Return the size of the basic block ignoring debug instructions
LLVM_ABI
filter_iterator<BasicBlock::const_iterator,
std::function<bool(const Instruction &)>>::difference_type
sizeWithoutDebug() const;
/// Unlink 'this' from the containing function, but do not delete it.
LLVM_ABI void removeFromParent();

View file

@ -93,7 +93,7 @@ void FunctionPropertiesInfo::updateForBB(const BasicBlock &BB,
StoreInstCount += Direction;
}
}
TotalInstructionCount += Direction * BB.sizeWithoutDebug();
TotalInstructionCount += Direction * BB.size();
if (EnableDetailedFunctionProperties) {
unsigned SuccessorCount = succ_size(&BB);
@ -145,7 +145,7 @@ void FunctionPropertiesInfo::updateForBB(const BasicBlock &BB,
SwitchSuccessorCount += Direction * SI->getNumSuccessors();
}
for (const Instruction &I : BB.instructionsWithoutDebug()) {
for (const Instruction &I : BB) {
if (I.isCast())
CastInstructionCount += Direction;

View file

@ -180,8 +180,9 @@ Embedding Embedder::computeEmbeddings(const BasicBlock &BB) const {
Embedding BBVector(Dimension, 0);
// We consider only the non-debug and non-pseudo instructions
for (const auto &I : BB.instructionsWithoutDebug())
BBVector += computeEmbeddings(I);
for (const auto &I : BB)
if (!I.isDebugOrPseudoInst())
BBVector += computeEmbeddings(I);
return BBVector;
}

View file

@ -1075,9 +1075,8 @@ void IRSimilarityCandidate::createCanonicalRelationFrom(
// If the basic block is the starting block, then the shared instruction may
// not be the first instruction in the block, it will be the first
// instruction in the similarity region.
Value *FirstOutlineInst = BB == getStartBB()
? frontInstruction()
: &*BB->instructionsWithoutDebug().begin();
Value *FirstOutlineInst =
BB == getStartBB() ? frontInstruction() : &*BB->begin();
unsigned FirstInstGVN = *getGVN(FirstOutlineInst);
unsigned FirstInstCanonNum = *getCanonicalNum(FirstInstGVN);

View file

@ -179,7 +179,7 @@ void KernelInfo::updateForBB(const BasicBlock &BB,
const Function &F = *BB.getParent();
const Module &M = *F.getParent();
const DataLayout &DL = M.getDataLayout();
for (const Instruction &I : BB.instructionsWithoutDebug()) {
for (const Instruction &I : BB) {
if (const AllocaInst *Alloca = dyn_cast<AllocaInst>(&I)) {
++Allocas;
TypeSize::ScalarTy StaticSize = 0;
@ -193,6 +193,8 @@ void KernelInfo::updateForBB(const BasicBlock &BB,
}
remarkAlloca(ORE, F, *Alloca, StaticSize);
} else if (const CallBase *Call = dyn_cast<CallBase>(&I)) {
if (isa<PseudoProbeInst>(Call))
continue;
SmallString<40> CallKind;
SmallString<40> RemarkKind;
if (Call->isIndirectCall()) {

View file

@ -26,13 +26,12 @@ SmallVector<const BasicBlock *, 8> findBBwithCalls(const Function &F,
auto findCallInst = [&IndirectCall](const Instruction &I) {
if (auto Call = dyn_cast<CallBase>(&I))
return Call->isIndirectCall() ? IndirectCall : true;
else
return false;
if (!isa<PseudoProbeInst>(Call))
return Call->isIndirectCall() ? IndirectCall : true;
return false;
};
for (auto &BB : F)
if (findCallInst(*BB.getTerminator()) ||
llvm::any_of(BB.instructionsWithoutDebug(), findCallInst))
if (findCallInst(*BB.getTerminator()) || llvm::any_of(BB, findCallInst))
BBs.emplace_back(&BB);
return BBs;
@ -55,7 +54,7 @@ void SpeculateQuery::findCalles(const BasicBlock *BB,
if (auto DirectCall = dyn_cast<Function>(CalledValue))
CallesNames.insert(DirectCall->getName());
};
for (auto &I : BB->instructionsWithoutDebug())
for (auto &I : *BB)
if (auto CI = dyn_cast<CallInst>(&I))
getCalledFunction(CI);

View file

@ -201,33 +201,6 @@ void BasicBlock::setParent(Function *parent) {
InstList.setSymTabObject(&Parent, parent);
}
iterator_range<filter_iterator<BasicBlock::const_iterator,
std::function<bool(const Instruction &)>>>
BasicBlock::instructionsWithoutDebug(bool SkipPseudoOp) const {
std::function<bool(const Instruction &)> Fn = [=](const Instruction &I) {
return !isa<DbgInfoIntrinsic>(I) &&
!(SkipPseudoOp && isa<PseudoProbeInst>(I));
};
return make_filter_range(*this, Fn);
}
iterator_range<
filter_iterator<BasicBlock::iterator, std::function<bool(Instruction &)>>>
BasicBlock::instructionsWithoutDebug(bool SkipPseudoOp) {
std::function<bool(Instruction &)> Fn = [=](Instruction &I) {
return !isa<DbgInfoIntrinsic>(I) &&
!(SkipPseudoOp && isa<PseudoProbeInst>(I));
};
return make_filter_range(*this, Fn);
}
filter_iterator<BasicBlock::const_iterator,
std::function<bool(const Instruction &)>>::difference_type
BasicBlock::sizeWithoutDebug() const {
return std::distance(instructionsWithoutDebug().begin(),
instructionsWithoutDebug().end());
}
void BasicBlock::removeFromParent() {
getParent()->getBasicBlockList().remove(getIterator());
}

View file

@ -366,8 +366,7 @@ const DataLayout &Function::getDataLayout() const {
unsigned Function::getInstructionCount() const {
unsigned NumInstrs = 0;
for (const BasicBlock &BB : BasicBlocks)
NumInstrs += std::distance(BB.instructionsWithoutDebug().begin(),
BB.instructionsWithoutDebug().end());
NumInstrs += BB.size();
return NumInstrs;
}

View file

@ -6490,7 +6490,7 @@ bool AArch64TTIImpl::preferPredicateOverEpilogue(TailFoldingInfo *TFI) const {
// with an unpredicated loop.
unsigned NumInsns = 0;
for (BasicBlock *BB : TFI->LVL->getLoop()->blocks()) {
NumInsns += BB->sizeWithoutDebug();
NumInsns += BB->size();
}
// We expect 4 of these to be a IV PHI, IV add, IV compare and branch.

View file

@ -2562,8 +2562,8 @@ static bool canTailPredicateLoop(Loop *L, LoopInfo *LI, ScalarEvolution &SE,
int ICmpCount = 0;
for (BasicBlock *BB : L->blocks()) {
for (Instruction &I : BB->instructionsWithoutDebug()) {
if (isa<PHINode>(&I))
for (Instruction &I : *BB) {
if (isa<PHINode>(I) || isa<PseudoProbeInst>(I))
continue;
if (!canTailPredicateInstruction(I, ICmpCount)) {
LLVM_DEBUG(dbgs() << "Instruction not allowed: "; I.dump());

View file

@ -2092,7 +2092,7 @@ static void inferAttrsFromFunctionBodies(const SCCNodeSet &SCCNodes,
static bool mayHaveRecursiveCallee(Function &F,
bool AnyFunctionsAddressIsTaken = true) {
for (const auto &BB : F) {
for (const auto &I : BB.instructionsWithoutDebug()) {
for (const auto &I : BB) {
if (const auto *CB = dyn_cast<CallBase>(&I)) {
const Function *Callee = CB->getCalledFunction();
if (!Callee || Callee == &F)

View file

@ -287,7 +287,7 @@ static InstructionCost getOutliningBenefit(ArrayRef<BasicBlock *> Region,
// with \ref getOutliningPenalty is needed to model the costs of terminators.
InstructionCost Benefit = 0;
for (BasicBlock *BB : Region)
for (Instruction &I : BB->instructionsWithoutDebug())
for (Instruction &I : *BB)
if (&I != BB->getTerminator())
Benefit +=
TTI.getInstructionCost(&I, TargetTransformInfo::TCK_CodeSize);

View file

@ -2288,8 +2288,7 @@ static bool nextIRInstructionDataMatchesNextInst(IRInstructionData &ID) {
if (!ID.Inst->isTerminator())
NextModuleInst = ID.Inst->getNextNode();
else if (NextIDLInst != nullptr)
NextModuleInst =
&*NextIDIt->Inst->getParent()->instructionsWithoutDebug().begin();
NextModuleInst = &*NextIDIt->Inst->getParent()->begin();
if (NextIDLInst && NextIDLInst != NextModuleInst)
return false;

View file

@ -408,7 +408,7 @@ bool MergeFunctions::doFunctionalCheck(std::vector<WeakTrackingVH> &Worklist) {
/// instance of this would be CFI checks for function-local types.
static bool hasDistinctMetadataIntrinsic(const Function &F) {
for (const BasicBlock &BB : F) {
for (const Instruction &I : BB.instructionsWithoutDebug()) {
for (const Instruction &I : BB) {
if (!isa<IntrinsicInst>(&I))
continue;
@ -703,7 +703,7 @@ static bool canCreateThunkFor(Function *F) {
// Don't merge tiny functions using a thunk, since it can just end up
// making the function larger.
if (F->size() == 1) {
if (F->front().sizeWithoutDebug() < 2) {
if (F->front().size() < 2) {
LLVM_DEBUG(dbgs() << "canCreateThunkFor: " << F->getName()
<< " is too small to bother creating a thunk for\n");
return false;

View file

@ -799,7 +799,7 @@ PartialInlinerImpl::computeBBInlineCost(BasicBlock *BB,
InstructionCost InlineCost = 0;
const DataLayout &DL = BB->getDataLayout();
int InstrCost = InlineConstants::getInstrCost();
for (Instruction &I : BB->instructionsWithoutDebug()) {
for (Instruction &I : *BB) {
// Skip free instructions.
switch (I.getOpcode()) {
case Instruction::BitCast:

View file

@ -4071,8 +4071,9 @@ static Instruction *tryToMoveFreeBeforeNullTest(CallInst &FI,
// If there are more than 2 instructions, check that they are noops
// i.e., they won't hurt the performance of the generated code.
if (FreeInstrBB->size() != 2) {
for (const Instruction &Inst : FreeInstrBB->instructionsWithoutDebug()) {
if (&Inst == &FI || &Inst == FreeInstrBBTerminator)
for (const Instruction &Inst : *FreeInstrBB) {
if (&Inst == &FI || &Inst == FreeInstrBBTerminator ||
isa<PseudoProbeInst>(Inst))
continue;
auto *Cast = dyn_cast<CastInst>(&Inst);
if (!Cast || !Cast->isNoopCast(DL))

View file

@ -920,7 +920,7 @@ private:
BasicBlock *VisitedBB = getClonedBB(BB, NextState, DuplicateMap);
if (!VisitedBB) {
Metrics.analyzeBasicBlock(BB, *TTI, EphValues);
NumClonedInst += BB->sizeWithoutDebug();
NumClonedInst += BB->size();
DuplicateMap[BB].push_back({BB, NextState});
}
@ -938,7 +938,7 @@ private:
if (VisitedBB)
continue;
Metrics.analyzeBasicBlock(BB, *TTI, EphValues);
NumClonedInst += BB->sizeWithoutDebug();
NumClonedInst += BB->size();
DuplicateMap[BB].push_back({BB, NextState});
}
@ -981,7 +981,7 @@ private:
uint64_t NumOrigInst = 0;
uint64_t NumOuterUseBlock = 0;
for (auto *BB : DuplicateMap.keys()) {
NumOrigInst += BB->sizeWithoutDebug();
NumOrigInst += BB->size();
// Only unduplicated blocks with single predecessor require new phi
// nodes.
for (auto *Succ : successors(BB))

View file

@ -2377,10 +2377,7 @@ bool LoopIdiomRecognize::isProfitableToInsertFFS(Intrinsic::ID IntrinID,
const Value *Args[] = {InitX,
ConstantInt::getBool(InitX->getContext(), ZeroCheck)};
// @llvm.dbg doesn't count as they have no semantic effect.
auto InstWithoutDebugIt = CurLoop->getHeader()->instructionsWithoutDebug();
uint32_t HeaderSize =
std::distance(InstWithoutDebugIt.begin(), InstWithoutDebugIt.end());
uint32_t HeaderSize = CurLoop->getHeader()->size();
IntrinsicCostAttributes Attrs(IntrinID, InitX->getType(), Args);
InstructionCost Cost = TTI->getIntrinsicInstrCost(

View file

@ -1438,10 +1438,10 @@ bool LoopInterchangeLegality::canInterchangeLoops(unsigned InnerLoopId,
}
// Check if outer and inner loop contain legal instructions only.
for (auto *BB : OuterLoop->blocks())
for (Instruction &I : BB->instructionsWithoutDebug())
for (Instruction &I : *BB)
if (CallInst *CI = dyn_cast<CallInst>(&I)) {
// readnone functions do not prevent interchanging.
if (CI->onlyWritesMemory())
if (CI->onlyWritesMemory() || isa<PseudoProbeInst>(CI))
continue;
LLVM_DEBUG(
dbgs() << "Loops with call instructions cannot be interchanged "

View file

@ -101,7 +101,7 @@ class MergedLoadStoreMotion {
// where Size0 and Size1 are the #instructions on the two sides of
// the diamond. The constant chosen here is arbitrary. Compiler Time
// Control is enforced by the check Size0 * Size1 < MagicCompileTimeControl.
const int MagicCompileTimeControl = 250;
const unsigned MagicCompileTimeControl = 250;
const bool SplitFooterBB;
public:
@ -317,9 +317,8 @@ bool MergedLoadStoreMotion::mergeStores(BasicBlock *HeadBB) {
if (!SplitFooterBB && TailBB->hasNPredecessorsOrMore(3))
return false;
// #Instructions in Pred1 for Compile Time Control
auto InstsNoDbg = Pred1->instructionsWithoutDebug();
int Size1 = std::distance(InstsNoDbg.begin(), InstsNoDbg.end());
int NStores = 0;
unsigned Size1 = Pred1->size();
unsigned NStores = 0;
for (BasicBlock::reverse_iterator RBI = Pred0->rbegin(), RBE = Pred0->rend();
RBI != RBE;) {

View file

@ -316,7 +316,7 @@ static BasicBlock *getCommonExitBlock(const SetVector<BasicBlock *> &Blocks) {
CodeExtractorAnalysisCache::CodeExtractorAnalysisCache(Function &F) {
for (BasicBlock &BB : F) {
for (Instruction &II : BB.instructionsWithoutDebug())
for (Instruction &II : BB)
if (auto *AI = dyn_cast<AllocaInst>(&II))
Allocas.push_back(AI);
@ -325,7 +325,7 @@ CodeExtractorAnalysisCache::CodeExtractorAnalysisCache(Function &F) {
}
void CodeExtractorAnalysisCache::findSideEffectInfoForBlock(BasicBlock &BB) {
for (Instruction &II : BB.instructionsWithoutDebug()) {
for (Instruction &II : BB) {
unsigned Opcode = II.getOpcode();
Value *MemAddr = nullptr;
switch (Opcode) {
@ -352,7 +352,7 @@ void CodeExtractorAnalysisCache::findSideEffectInfoForBlock(BasicBlock &BB) {
default: {
IntrinsicInst *IntrInst = dyn_cast<IntrinsicInst>(&II);
if (IntrInst) {
if (IntrInst->isLifetimeStartOrEnd())
if (IntrInst->isLifetimeStartOrEnd() || isa<PseudoProbeInst>(IntrInst))
break;
SideEffectingBlocks.insert(&BB);
return;

View file

@ -638,7 +638,7 @@ ReprocessLoop:
// comparison and the branch.
bool AllInvariant = true;
bool AnyInvariant = false;
for (auto I = ExitingBlock->instructionsWithoutDebug().begin(); &*I != BI; ) {
for (auto I = ExitingBlock->begin(); &*I != BI;) {
Instruction *Inst = &*I++;
if (Inst == CI)
continue;

View file

@ -77,7 +77,7 @@ bool isAsmOnly(const Function &F) {
if (!F.hasFnAttribute(Attribute::AttrKind::Naked))
return false;
for (const auto &BB : F)
for (const auto &I : drop_end(BB.instructionsWithoutDebug())) {
for (const auto &I : drop_end(BB)) {
const auto *CB = dyn_cast<CallBase>(&I);
if (!CB || !CB->isInlineAsm())
return false;

View file

@ -3044,11 +3044,14 @@ static Value *isSafeToSpeculateStore(Instruction *I, BasicBlock *BrBB,
unsigned MaxNumInstToLookAt = 9;
// Skip pseudo probe intrinsic calls which are not really killing any memory
// accesses.
for (Instruction &CurI : reverse(BrBB->instructionsWithoutDebug(true))) {
for (Instruction &CurI : reverse(*BrBB)) {
if (!MaxNumInstToLookAt)
break;
--MaxNumInstToLookAt;
if (isa<PseudoProbeInst>(CurI))
continue;
// Could be calling an instruction that affects memory like free().
if (CurI.mayWriteToMemory() && !isa<StoreInst>(CurI))
return nullptr;
@ -3467,7 +3470,7 @@ static bool blockIsSimpleEnoughToThreadThrough(BasicBlock *BB,
// Walk the loop in reverse so that we can identify ephemeral values properly
// (values only feeding assumes).
for (Instruction &I : reverse(BB->instructionsWithoutDebug(false))) {
for (Instruction &I : reverse(*BB)) {
// Can't fold blocks that contain noduplicate or convergent calls.
if (CallInst *CI = dyn_cast<CallInst>(&I))
if (CI->cannotDuplicate() || CI->isConvergent())
@ -4362,7 +4365,7 @@ static bool mergeConditionalStoreToAddress(
InstructionCost Cost = 0;
InstructionCost Budget =
PHINodeFoldingThreshold * TargetTransformInfo::TCC_Basic;
for (auto &I : BB->instructionsWithoutDebug(false)) {
for (auto &I : *BB) {
// Consider terminator instruction to be free.
if (I.isTerminator())
continue;
@ -4676,7 +4679,7 @@ static bool SimplifyCondBranchToCondBranch(CondBrInst *PBI, CondBrInst *BI,
// fold the conditions into logical ops and one cond br.
// Ignore dbg intrinsics.
if (&*BB->instructionsWithoutDebug(false).begin() != BI)
if (&*BB->begin() != BI)
return false;
int PBIOp, BIOp;
@ -6387,7 +6390,7 @@ getCaseResults(SwitchInst *SI, ConstantInt *CaseVal, BasicBlock *CaseDest,
// which we can constant-propagate the CaseVal, continue to its successor.
SmallDenseMap<Value *, Constant *> ConstantPool;
ConstantPool.insert(std::make_pair(SI->getCondition(), CaseVal));
for (Instruction &I : CaseDest->instructionsWithoutDebug(false)) {
for (Instruction &I : *CaseDest) {
if (I.isTerminator()) {
// If the terminator is a simple branch, continue to the next block.
if (I.getNumSuccessors() != 1 || I.isSpecialTerminator())
@ -8246,7 +8249,7 @@ bool SimplifyCFGOpt::simplifySwitch(SwitchInst *SI, IRBuilder<> &Builder) {
// If the block only contains the switch, see if we can fold the block
// away into any preds.
if (SI == &*BB->instructionsWithoutDebug(false).begin())
if (SI == &*BB->begin())
if (foldValueComparisonIntoPredecessors(SI, Builder))
return requestResimplify();
}
@ -8604,15 +8607,15 @@ bool SimplifyCFGOpt::simplifyCondBranch(CondBrInst *BI, IRBuilder<> &Builder) {
return requestResimplify();
// This block must be empty, except for the setcond inst, if it exists.
// Ignore dbg and pseudo intrinsics.
auto I = BB->instructionsWithoutDebug(true).begin();
if (&*I == BI) {
if (foldValueComparisonIntoPredecessors(BI, Builder))
return requestResimplify();
} else if (&*I == cast<Instruction>(BI->getCondition())) {
++I;
if (&*I == BI && foldValueComparisonIntoPredecessors(BI, Builder))
return requestResimplify();
// Ignore pseudo intrinsics.
for (auto &I : *BB) {
if (isa<PseudoProbeInst>(I) ||
&I == cast<Instruction>(BI->getCondition()))
continue;
if (&I == BI)
if (foldValueComparisonIntoPredecessors(BI, Builder))
return requestResimplify();
break;
}
}

View file

@ -327,7 +327,7 @@ bool LoopIdiomVectorize::recognizeByteCompare() {
// %cmp.not = icmp eq i32 %inc, %n
// br i1 %cmp.not, label %while.end, label %while.body
//
if (LoopBlocks[0]->sizeWithoutDebug() > 4)
if (LoopBlocks[0]->size() > 4)
return false;
// The second block should contain 7 instructions, e.g.
@ -341,7 +341,7 @@ bool LoopIdiomVectorize::recognizeByteCompare() {
// %cmp.not.ld = icmp eq i8 %load.a, %load.b
// br i1 %cmp.not.ld, label %while.cond, label %while.end
//
if (LoopBlocks[1]->sizeWithoutDebug() > 7)
if (LoopBlocks[1]->size() > 7)
return false;
// The incoming value to the PHI node from the loop should be an add of 1.
@ -1043,10 +1043,8 @@ bool LoopIdiomVectorize::recognizeFindFirstByte() {
// Check instruction counts.
auto LoopBlocks = CurLoop->getBlocks();
if (LoopBlocks[0]->sizeWithoutDebug() > 3 ||
LoopBlocks[1]->sizeWithoutDebug() > 4 ||
LoopBlocks[2]->sizeWithoutDebug() > 3 ||
LoopBlocks[3]->sizeWithoutDebug() > 3)
if (LoopBlocks[0]->size() > 3 || LoopBlocks[1]->size() > 4 ||
LoopBlocks[2]->size() > 3 || LoopBlocks[3]->size() > 3)
return false;
// Check that no instruction other than IndPhi has outside uses.

View file

@ -4590,7 +4590,7 @@ void LoopVectorizationCostModel::collectElementTypesForWidening() {
// For each block.
for (BasicBlock *BB : TheLoop->blocks()) {
// For each instruction in the loop.
for (Instruction &I : BB->instructionsWithoutDebug()) {
for (Instruction &I : *BB) {
Type *T = I.getType();
// Skip ignored values.
@ -5180,7 +5180,7 @@ InstructionCost LoopVectorizationCostModel::expectedCost(ElementCount VF) {
InstructionCost BlockCost;
// For each instruction in the old loop.
for (Instruction &I : BB->instructionsWithoutDebug()) {
for (Instruction &I : *BB) {
// Skip ignored values.
if (ValuesToIgnore.count(&I) || ValuesToIgnoreForVF.count(&I) ||
(VF.isVector() && VecValuesToIgnore.count(&I)))

View file

@ -184,7 +184,7 @@ void PlainCFGBuilder::createVPInstructionsForVPBB(VPBasicBlock *VPBB,
BasicBlock *BB) {
VPIRBuilder.setInsertPoint(VPBB);
// TODO: Model and preserve debug intrinsics in VPlan.
for (Instruction &InstRef : BB->instructionsWithoutDebug(false)) {
for (Instruction &InstRef : *BB) {
Instruction *Inst = &InstRef;
// There shouldn't be any VPValue for Inst at this point. Otherwise, we

View file

@ -68,7 +68,9 @@ TripletResult IR2VecTool::generateTriplets(const Function &F) const {
bool HasPrevOpcode = false;
for (const BasicBlock &BB : F) {
for (const auto &I : BB.instructionsWithoutDebug()) {
for (const auto &I : BB) {
if (I.isDebugOrPseudoInst())
continue;
unsigned Opcode = Vocabulary::getIndex(I.getOpcode());
unsigned TypeID = Vocabulary::getIndex(I.getType()->getTypeID());

View file

@ -129,7 +129,7 @@ int main(int argc, const char *argv[]) {
unsigned InstructionNumber = 1;
for (Function &F : *ModuleToAnalyze)
for (BasicBlock &BB : F)
for (Instruction &I : BB.instructionsWithoutDebug())
for (Instruction &I : BB)
LLVMInstNum[&I]= InstructionNumber++;
// The similarity identifier we will use to find the similar sections.

View file

@ -100,44 +100,6 @@ TEST(BasicBlockTest, PhiRange) {
for (auto Pair : zip(Range1, Range2)) \
EXPECT_EQ(&std::get<0>(Pair), std::get<1>(Pair));
TEST(BasicBlockTest, TestInstructionsWithoutDebug) {
LLVMContext Ctx;
Module *M = new Module("MyModule", Ctx);
Type *ArgTy1[] = {PointerType::getUnqual(Ctx)};
FunctionType *FT = FunctionType::get(Type::getVoidTy(Ctx), ArgTy1, false);
Argument *V = new Argument(Type::getInt32Ty(Ctx));
Function *F = Function::Create(FT, Function::ExternalLinkage, "", M);
Function *DbgDeclare =
Intrinsic::getOrInsertDeclaration(M, Intrinsic::dbg_declare);
Function *DbgValue =
Intrinsic::getOrInsertDeclaration(M, Intrinsic::dbg_value);
Value *DIV = MetadataAsValue::get(Ctx, (Metadata *)nullptr);
SmallVector<Value *, 3> Args = {DIV, DIV, DIV};
BasicBlock *BB1 = BasicBlock::Create(Ctx, "", F);
const BasicBlock *BBConst = BB1;
IRBuilder<> Builder1(BB1);
AllocaInst *Var = Builder1.CreateAlloca(Builder1.getInt8Ty());
Builder1.CreateCall(DbgValue, Args);
Instruction *AddInst = cast<Instruction>(Builder1.CreateAdd(V, V));
Instruction *MulInst = cast<Instruction>(Builder1.CreateMul(AddInst, V));
Builder1.CreateCall(DbgDeclare, Args);
Instruction *SubInst = cast<Instruction>(Builder1.CreateSub(MulInst, V));
SmallVector<Instruction *, 4> Exp = {Var, AddInst, MulInst, SubInst};
CHECK_ITERATORS(BB1->instructionsWithoutDebug(), Exp);
CHECK_ITERATORS(BBConst->instructionsWithoutDebug(), Exp);
EXPECT_EQ(static_cast<size_t>(BB1->sizeWithoutDebug()), Exp.size());
EXPECT_EQ(static_cast<size_t>(BBConst->sizeWithoutDebug()), Exp.size());
delete M;
delete V;
}
TEST(BasicBlockTest, ComesBefore) {
const char *ModuleString = R"(define i32 @f(i32 %x) {
%add = add i32 %x, 42