/// \brief Initialize the types and constants used in the pass
bool AMDGPUStructurizeCFG::doInitialization(Region *R, RGPassManager &RGM) {
-
LLVMContext &Context = R->getEntry()->getContext();
Boolean = Type::getInt1Ty(Context);
/// \brief Build up the general order of nodes
void AMDGPUStructurizeCFG::orderNodes() {
-
scc_iterator<Region *> I = scc_begin(ParentRegion),
E = scc_end(ParentRegion);
for (Order.clear(); I != E; ++I) {
/// \brief Build blocks and loop predicates
void AMDGPUStructurizeCFG::buildPredicate(BranchInst *Term, unsigned Idx,
BBPredicates &Pred, bool Invert) {
-
Value *True = Invert ? BoolFalse : BoolTrue;
Value *False = Invert ? BoolTrue : BoolFalse;
/// \brief Analyze the successors of each block and build up predicates
void AMDGPUStructurizeCFG::analyzeBlock(BasicBlock *BB) {
-
pred_iterator PI = pred_begin(BB), PE = pred_end(BB);
BBPredicates &Pred = Predicates[BB];
/// \brief Analyze the conditions leading to loop to a previous block
void AMDGPUStructurizeCFG::analyzeLoop(BasicBlock *BB, unsigned &LoopIdx) {
-
BranchInst *Term = cast<BranchInst>(BB->getTerminator());
for (unsigned i = 0, e = Term->getNumSuccessors(); i != e; ++i) {
/// \brief Collect various loop and predicate infos
void AMDGPUStructurizeCFG::collectInfos() {
-
unsigned Number = 0, LoopIdx = ~0;
// Reset predicate
/// \brief Does A dominate all the predicates of B ?
bool AMDGPUStructurizeCFG::dominatesPredicates(BasicBlock *A, BasicBlock *B) {
-
BBPredicates &Preds = Predicates[B];
for (BBPredicates::iterator PI = Preds.begin(), PE = Preds.end();
PI != PE; ++PI) {
/// \brief Remove phi values from all successors and the remove the terminator.
void AMDGPUStructurizeCFG::killTerminator(BasicBlock *BB) {
-
TerminatorInst *Term = BB->getTerminator();
if (!Term)
return;
/// Second: Handle the first successor directly if the resulting nodes successor
/// predicates are still dominated by the original entry
RegionNode *AMDGPUStructurizeCFG::skipChained(RegionNode *Node) {
-
BasicBlock *Entry = Node->getEntry();
// Skip forward as long as it is just a linear flow
/// \brief Remove all PHI values coming from "From" into "To" and remember
/// them in DeletedPhis
void AMDGPUStructurizeCFG::delPhiValues(BasicBlock *From, BasicBlock *To) {
-
PhiMap &Map = DeletedPhis[To];
for (BasicBlock::iterator I = To->begin(), E = To->end();
I != E && isa<PHINode>(*I);) {
/// \brief Add the PHI values back once we knew the new predecessor
void AMDGPUStructurizeCFG::addPhiValues(BasicBlock *From, BasicBlock *To) {
-
if (!DeletedPhis.count(To))
return;
/// \brief Create a new flow node and update dominator tree and region info
BasicBlock *AMDGPUStructurizeCFG::getNextFlow(BasicBlock *Prev) {
-
LLVMContext &Context = Func->getContext();
BasicBlock *Insert = Order.empty() ? ParentRegion->getExit() :
Order.back()->getEntry();
/// \brief Can we predict that this node will always be called?
bool AMDGPUStructurizeCFG::isPredictableTrue(BasicBlock *Prev,
BasicBlock *Node) {
-
BBPredicates &Preds = Predicates[Node];
bool Dominated = false;
/// instructions at node exits
BasicBlock *AMDGPUStructurizeCFG::wireFlowBlock(BasicBlock *Prev,
RegionNode *Node) {
-
BasicBlock *Entry = Node->getEntry();
if (LoopStart == Entry) {
/// After this function control flow looks like it should be, but
/// branches only have undefined conditions.
void AMDGPUStructurizeCFG::createFlow() {
-
DeletedPhis.clear();
BasicBlock *Prev = Order.pop_back_val()->getEntry();
/// \brief Insert the missing branch conditions
void AMDGPUStructurizeCFG::insertConditions() {
-
SSAUpdater PhiInserter;
for (BBVector::iterator FI = FlowsInserted.begin(), FE = FlowsInserted.end();
/// Handle a rare case where the disintegrated nodes instructions
/// no longer dominate all their uses. Not sure if this is really nessasary
void AMDGPUStructurizeCFG::rebuildSSA() {
-
SSAUpdater Updater;
for (Region::block_iterator I = ParentRegion->block_begin(),
E = ParentRegion->block_end();
/// \brief Run the transformation for each region found
bool AMDGPUStructurizeCFG::runOnRegion(Region *R, RGPassManager &RGM) {
-
if (R->isTopLevelRegion())
return false;
}
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
-
AU.addRequired<DominatorTree>();
AU.addPreserved<DominatorTree>();
FunctionPass::getAnalysisUsage(AU);
/// \brief Initialize all the types and constants used in the pass
bool SIAnnotateControlFlow::doInitialization(Module &M) {
-
LLVMContext &Context = M.getContext();
Void = Type::getVoidTy(Context);
/// \brief Can the condition represented by this PHI node treated like
/// an "Else" block?
bool SIAnnotateControlFlow::isElse(PHINode *Phi) {
-
BasicBlock *IDom = DT->getNode(Phi->getParent())->getIDom()->getBlock();
for (unsigned i = 0, e = Phi->getNumIncomingValues(); i != e; ++i) {
if (Phi->getIncomingBlock(i) == IDom) {
/// \brief Recursively handle the condition leading to a loop
void SIAnnotateControlFlow::handleLoopCondition(Value *Cond) {
-
if (PHINode *Phi = dyn_cast<PHINode>(Cond)) {
// Handle all non constant incoming values first
/// \brief Handle a back edge (loop)
void SIAnnotateControlFlow::handleLoop(BranchInst *Term) {
-
BasicBlock *Target = Term->getSuccessor(1);
PHINode *Broken = PHINode::Create(Int64, 0, "", &Target->front());
/// \brief Annotate the control flow with intrinsics so the backend can
/// recognize if/then/else and loops.
bool SIAnnotateControlFlow::runOnFunction(Function &F) {
-
DT = &getAnalysis<DominatorTree>();
for (df_iterator<BasicBlock *> I = df_begin(&F.getEntryBlock()),
/// \brief Create the annotation pass
FunctionPass *llvm::createSIAnnotateControlFlowPass() {
-
return new SIAnnotateControlFlow();
}
}
void SILowerControlFlowPass::Skip(MachineInstr &From, MachineOperand &To) {
-
unsigned NumInstr = 0;
for (MachineBasicBlock *MBB = *From.getParent()->succ_begin();
}
void SILowerControlFlowPass::If(MachineInstr &MI) {
-
MachineBasicBlock &MBB = *MI.getParent();
DebugLoc DL = MI.getDebugLoc();
unsigned Reg = MI.getOperand(0).getReg();
}
void SILowerControlFlowPass::Else(MachineInstr &MI) {
-
MachineBasicBlock &MBB = *MI.getParent();
DebugLoc DL = MI.getDebugLoc();
unsigned Dst = MI.getOperand(0).getReg();
}
void SILowerControlFlowPass::Break(MachineInstr &MI) {
-
MachineBasicBlock &MBB = *MI.getParent();
DebugLoc DL = MI.getDebugLoc();
}
void SILowerControlFlowPass::IfBreak(MachineInstr &MI) {
-
MachineBasicBlock &MBB = *MI.getParent();
DebugLoc DL = MI.getDebugLoc();
}
void SILowerControlFlowPass::ElseBreak(MachineInstr &MI) {
-
MachineBasicBlock &MBB = *MI.getParent();
DebugLoc DL = MI.getDebugLoc();
}
void SILowerControlFlowPass::Loop(MachineInstr &MI) {
-
MachineBasicBlock &MBB = *MI.getParent();
DebugLoc DL = MI.getDebugLoc();
unsigned Src = MI.getOperand(0).getReg();
}
void SILowerControlFlowPass::EndCf(MachineInstr &MI) {
-
MachineBasicBlock &MBB = *MI.getParent();
DebugLoc DL = MI.getDebugLoc();
unsigned Reg = MI.getOperand(0).getReg();
}
void SILowerControlFlowPass::Branch(MachineInstr &MI) {
-
MachineBasicBlock *Next = MI.getParent()->getNextNode();
MachineBasicBlock *Target = MI.getOperand(0).getMBB();
if (Target == Next)
}
bool SILowerControlFlowPass::runOnMachineFunction(MachineFunction &MF) {
-
bool HaveCf = false;
for (MachineFunction::iterator BI = MF.begin(), BE = MF.end();