-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Description
-
主体逻辑: 如果发现某一条指令是出现操作结果没有被使用的情况,就删除这条指令,并且记录这条指令的操作数,将它们加入到WorkList中,查看它们是否也是dead的,如果是,就继续执行清除。
static bool eliminateDeadCode(Function &F, TargetLibraryInfo *TLI) { bool MadeChange = false; SmallSetVector<Instruction *, 16> WorkList; // Iterate over the original function, only adding insts to the worklist // if they actually need to be revisited. This avoids having to pre-init // the worklist with the entire function's worth of instructions. for (Instruction &I : llvm::make_early_inc_range(instructions(F))) { // We're visiting this instruction now, so make sure it's not in the // worklist from an earlier visit. if (!WorkList.count(&I)) MadeChange |= DCEInstruction(&I, WorkList, TLI); } while (!WorkList.empty()) { Instruction *I = WorkList.pop_back_val(); MadeChange |= DCEInstruction(I, WorkList, TLI); } return MadeChange; }static bool DCEInstruction(Instruction *I, SmallSetVector<Instruction *, 16> &WorkList, const TargetLibraryInfo *TLI) { if (isInstructionTriviallyDead(I, TLI)) { if (!DebugCounter::shouldExecute(DCECounter)) return false; salvageDebugInfo(*I); salvageKnowledge(I); // Null out all of the instruction's operands to see if any operand becomes // dead as we go. for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) { Value *OpV = I->getOperand(i); I->setOperand(i, nullptr); if (!OpV->use_empty() || I == OpV) continue; // If the operand is an instruction that became dead as we nulled out the // operand, and if it is 'trivially' dead, delete it in a future loop // iteration. if (Instruction *OpI = dyn_cast<Instruction>(OpV)) if (isInstructionTriviallyDead(OpI, TLI)) WorkList.insert(OpI); } I->eraseFromParent(); ++DCEEliminated; return true; } return false; }
参考
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels