在LLVM中间表示中,如何为循环插入一条指令,该循环将在执行该循环之前执行一次?将指令插入预读器不起作用,因为对于某些循环,preheader为NULL。
答案 0 :(得分:4)
如果循环没有预读器,则可以创建新的预读器。
以下是http://www.cs.ucla.edu/classes/spring08/cs259/llvm-2.2/lib/Transforms/Utils/LoopSimplify.cpp或http://www.opensource.apple.com/source/clang/clang-23/clang/lib/Transforms/Utils/LoopSimplify.cpp示例(查找函数InsertPreheaderForLoop
并调用它)
/// InsertPreheaderForLoop - Once we discover that a loop doesn't have a
/// preheader, this method is called to insert one. This method has two phases:
/// preheader insertion and analysis updating.
///
void LoopSimplify::InsertPreheaderForLoop(Loop *L) {
BasicBlock *Header = L->getHeader();
// Compute the set of predecessors of the loop that are not in the loop.
std::vector<BasicBlock*> OutsideBlocks;
for (pred_iterator PI = pred_begin(Header), PE = pred_end(Header);
PI != PE; ++PI)
if (!L->contains(*PI)) // Coming in from outside the loop?
OutsideBlocks.push_back(*PI); // Keep track of it...
// Split out the loop pre-header.
BasicBlock *NewBB =
SplitBlockPredecessors(Header, ".preheader", OutsideBlocks);
//===--------------------------------------------------------------------===//
// Update analysis results now that we have performed the transformation
//
// We know that we have loop information to update... update it now.
if (Loop *Parent = L->getParentLoop())
Parent->addBasicBlockToLoop(NewBB, LI->getBase());
DT->splitBlock(NewBB);
if (DominanceFrontier *DF = getAnalysisToUpdate<DominanceFrontier>())
DF->splitBlock(NewBB);
// Make sure that NewBB is put someplace intelligent, which doesn't mess up
// code layout too horribly.
PlaceSplitBlockCarefully(NewBB, OutsideBlocks, L);
}