1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===-- AMDILCFGStructurizer.cpp - CFG Structurizer -----------------------===// 2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// 3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// The LLVM Compiler Infrastructure 4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// 5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// This file is distributed under the University of Illinois Open Source 6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// License. See LICENSE.TXT for details. 7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// 8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//==-----------------------------------------------------------------------===// 9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define DEBUGME 0 11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define DEBUG_TYPE "structcfg" 12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "AMDGPUInstrInfo.h" 14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "AMDIL.h" 15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "AMDILUtilityFunctions.h" 16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "llvm/ADT/SCCIterator.h" 17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "llvm/ADT/SmallVector.h" 18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "llvm/ADT/Statistic.h" 19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "llvm/Analysis/DominatorInternals.h" 20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "llvm/Analysis/Dominators.h" 21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "llvm/CodeGen/MachineDominators.h" 22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "llvm/CodeGen/MachineDominators.h" 23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "llvm/CodeGen/MachineFunction.h" 24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "llvm/CodeGen/MachineFunctionAnalysis.h" 25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "llvm/CodeGen/MachineFunctionPass.h" 26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "llvm/CodeGen/MachineFunctionPass.h" 27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "llvm/CodeGen/MachineInstrBuilder.h" 28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "llvm/CodeGen/MachineJumpTableInfo.h" 29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "llvm/CodeGen/MachineLoopInfo.h" 30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "llvm/CodeGen/MachineRegisterInfo.h" 31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "llvm/Target/TargetInstrInfo.h" 32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define FirstNonDebugInstr(A) A->begin() 34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgusing namespace llvm; 35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// TODO: move-begin. 37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===// 39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// 40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// Statistics for CFGStructurizer. 41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// 42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===// 43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgSTATISTIC(numSerialPatternMatch, "CFGStructurizer number of serial pattern " 45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "matched"); 46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgSTATISTIC(numIfPatternMatch, "CFGStructurizer number of if pattern " 47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "matched"); 48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgSTATISTIC(numLoopbreakPatternMatch, "CFGStructurizer number of loop-break " 49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "pattern matched"); 50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgSTATISTIC(numLoopcontPatternMatch, "CFGStructurizer number of loop-continue " 51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "pattern matched"); 52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgSTATISTIC(numLoopPatternMatch, "CFGStructurizer number of loop pattern " 53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "matched"); 54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgSTATISTIC(numClonedBlock, "CFGStructurizer cloned blocks"); 55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgSTATISTIC(numClonedInstr, "CFGStructurizer cloned instructions"); 56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===// 58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// 59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// Miscellaneous utility for CFGStructurizer. 60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// 61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===// 62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnamespace llvmCFGStruct 63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define SHOWNEWINSTR(i) \ 65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUGME) errs() << "New instr: " << *i << "\n" 66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define SHOWNEWBLK(b, msg) \ 68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgif (DEBUGME) { \ 69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << msg << "BB" << b->getNumber() << "size " << b->size(); \ 70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "\n"; \ 71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define SHOWBLK_DETAIL(b, msg) \ 74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgif (DEBUGME) { \ 75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (b) { \ 76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << msg << "BB" << b->getNumber() << "size " << b->size(); \ 77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org b->print(errs()); \ 78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "\n"; \ 79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } \ 80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define INVALIDSCCNUM -1 83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define INVALIDREGNUM 0 84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class LoopinfoT> 86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid PrintLoopinfo(const LoopinfoT &LoopInfo, llvm::raw_ostream &OS) { 87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (typename LoopinfoT::iterator iter = LoopInfo.begin(), 88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org iterEnd = LoopInfo.end(); 89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org iter != iterEnd; ++iter) { 90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (*iter)->print(OS, 0); 91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class NodeT> 95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ReverseVector(SmallVector<NodeT *, DEFAULT_VEC_SLOTS> &Src) { 96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org size_t sz = Src.size(); 97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (size_t i = 0; i < sz/2; ++i) { 98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org NodeT *t = Src[i]; 99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org Src[i] = Src[sz - i - 1]; 100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org Src[sz - i - 1] = t; 101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //end namespace llvmCFGStruct 105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===// 108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// 109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// MachinePostDominatorTree 110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// 111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===// 112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnamespace llvm { 114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// PostDominatorTree Class - Concrete subclass of DominatorTree that is used 116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// to compute the a post-dominator tree. 117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// 118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct MachinePostDominatorTree : public MachineFunctionPass { 119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static char ID; // Pass identification, replacement for typeid 120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org DominatorTreeBase<MachineBasicBlock> *DT; 121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org MachinePostDominatorTree() : MachineFunctionPass(ID) 122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org DT = new DominatorTreeBase<MachineBasicBlock>(true); //true indicate 124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // postdominator 125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ~MachinePostDominatorTree(); 128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual bool runOnMachineFunction(MachineFunction &MF); 130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual void getAnalysisUsage(AnalysisUsage &AU) const { 132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org AU.setPreservesAll(); 133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org MachineFunctionPass::getAnalysisUsage(AU); 134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inline const std::vector<MachineBasicBlock *> &getRoots() const { 137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return DT->getRoots(); 138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inline MachineDomTreeNode *getRootNode() const { 141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return DT->getRootNode(); 142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inline MachineDomTreeNode *operator[](MachineBasicBlock *BB) const { 145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return DT->getNode(BB); 146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inline MachineDomTreeNode *getNode(MachineBasicBlock *BB) const { 149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return DT->getNode(BB); 150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inline bool dominates(MachineDomTreeNode *A, MachineDomTreeNode *B) const { 153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return DT->dominates(A, B); 154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inline bool dominates(MachineBasicBlock *A, MachineBasicBlock *B) const { 157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return DT->dominates(A, B); 158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inline bool 161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org properlyDominates(const MachineDomTreeNode *A, MachineDomTreeNode *B) const { 162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return DT->properlyDominates(A, B); 163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inline bool 166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org properlyDominates(MachineBasicBlock *A, MachineBasicBlock *B) const { 167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return DT->properlyDominates(A, B); 168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inline MachineBasicBlock * 171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org findNearestCommonDominator(MachineBasicBlock *A, MachineBasicBlock *B) { 172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return DT->findNearestCommonDominator(A, B); 173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual void print(llvm::raw_ostream &OS, const Module *M = 0) const { 176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org DT->print(OS); 177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //end of namespace llvm 180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgchar MachinePostDominatorTree::ID = 0; 182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic RegisterPass<MachinePostDominatorTree> 183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgmachinePostDominatorTreePass("machinepostdomtree", 184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "MachinePostDominator Tree Construction", 185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org true, true); 186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//const PassInfo *const llvm::MachinePostDominatorsID 188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//= &machinePostDominatorTreePass; 189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool MachinePostDominatorTree::runOnMachineFunction(MachineFunction &F) { 191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org DT->recalculate(F); 192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //DEBUG(DT->dump()); 193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return false; 194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgMachinePostDominatorTree::~MachinePostDominatorTree() { 197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org delete DT; 198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===// 201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// 202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// supporting data structure for CFGStructurizer 203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// 204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===// 205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnamespace llvmCFGStruct 207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT> 209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct CFGStructTraits { 210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate <class InstrT> 213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass BlockInformation { 214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpublic: 215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool isRetired; 216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int sccNum; 217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //SmallVector<InstrT*, DEFAULT_VEC_SLOTS> succInstr; 218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //Instructions defining the corresponding successor. 219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockInformation() : isRetired(false), sccNum(INVALIDSCCNUM) {} 220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate <class BlockT, class InstrT, class RegiT> 223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass LandInformation { 224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpublic: 225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *landBlk; 226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org std::set<RegiT> breakInitRegs; //Registers that need to "reg = 0", before 227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //WHILELOOP(thisloop) init before entering 228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //thisloop. 229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org std::set<RegiT> contInitRegs; //Registers that need to "reg = 0", after 230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //WHILELOOP(thisloop) init after entering 231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //thisloop. 232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org std::set<RegiT> endbranchInitRegs; //Init before entering this loop, at loop 233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //land block, branch cond on this reg. 234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org std::set<RegiT> breakOnRegs; //registers that need to "if (reg) break 235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //endif" after ENDLOOP(thisloop) break 236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //outerLoopOf(thisLoop). 237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org std::set<RegiT> contOnRegs; //registers that need to "if (reg) continue 238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //endif" after ENDLOOP(thisloop) continue on 239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //outerLoopOf(thisLoop). 240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LandInformation() : landBlk(NULL) {} 241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //end of namespace llvmCFGStruct 244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===// 246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// 247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// CFGStructurizer 248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// 249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===// 250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnamespace llvmCFGStruct 252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// bixia TODO: port it to BasicBlock, not just MachineBasicBlock. 254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT> 255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass CFGStructurizer 256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpublic: 258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org typedef enum { 259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org Not_SinglePath = 0, 260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SinglePath_InPath = 1, 261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SinglePath_NotInPath = 2 262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } PathToKind; 263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpublic: 265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org typedef typename PassT::InstructionType InstrT; 266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org typedef typename PassT::FunctionType FuncT; 267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org typedef typename PassT::DominatortreeType DomTreeT; 268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org typedef typename PassT::PostDominatortreeType PostDomTreeT; 269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org typedef typename PassT::DomTreeNodeType DomTreeNodeT; 270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org typedef typename PassT::LoopinfoType LoopInfoT; 271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org typedef GraphTraits<FuncT *> FuncGTraits; 273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //typedef FuncGTraits::nodes_iterator BlockIterator; 274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org typedef typename FuncT::iterator BlockIterator; 275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org typedef typename FuncGTraits::NodeType BlockT; 277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org typedef GraphTraits<BlockT *> BlockGTraits; 278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org typedef GraphTraits<Inverse<BlockT *> > InvBlockGTraits; 279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //typedef BlockGTraits::succ_iterator InstructionIterator; 280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org typedef typename BlockT::iterator InstrIterator; 281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org typedef CFGStructTraits<PassT> CFGTraits; 283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org typedef BlockInformation<InstrT> BlockInfo; 284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org typedef std::map<BlockT *, BlockInfo *> BlockInfoMap; 285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org typedef int RegiT; 287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org typedef typename PassT::LoopType LoopT; 288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org typedef LandInformation<BlockT, InstrT, RegiT> LoopLandInfo; 289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org typedef std::map<LoopT *, LoopLandInfo *> LoopLandInfoMap; 290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //landing info for loop break 291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org typedef SmallVector<BlockT *, 32> BlockTSmallerVector; 292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpublic: 294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org CFGStructurizer(); 295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ~CFGStructurizer(); 296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /// Perform the CFG structurization 298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool run(FuncT &Func, PassT &Pass, const AMDGPURegisterInfo *tri); 299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /// Perform the CFG preparation 301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool prepare(FuncT &Func, PassT &Pass, const AMDGPURegisterInfo *tri); 302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgprivate: 304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void reversePredicateSetter(typename BlockT::iterator); 305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void orderBlocks(); 306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void printOrderedBlocks(llvm::raw_ostream &OS); 307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int patternMatch(BlockT *CurBlock); 308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int patternMatchGroup(BlockT *CurBlock); 309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int serialPatternMatch(BlockT *CurBlock); 311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int ifPatternMatch(BlockT *CurBlock); 312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int switchPatternMatch(BlockT *CurBlock); 313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int loopendPatternMatch(BlockT *CurBlock); 314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int loopPatternMatch(BlockT *CurBlock); 315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int loopbreakPatternMatch(LoopT *LoopRep, BlockT *LoopHeader); 317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int loopcontPatternMatch(LoopT *LoopRep, BlockT *LoopHeader); 318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //int loopWithoutBreak(BlockT *); 319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void handleLoopbreak (BlockT *ExitingBlock, LoopT *ExitingLoop, 321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *ExitBlock, LoopT *exitLoop, BlockT *landBlock); 322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void handleLoopcontBlock(BlockT *ContingBlock, LoopT *contingLoop, 323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *ContBlock, LoopT *contLoop); 324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool isSameloopDetachedContbreak(BlockT *Src1Block, BlockT *Src2Block); 325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int handleJumpintoIf(BlockT *HeadBlock, BlockT *TrueBlock, 326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *FalseBlock); 327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int handleJumpintoIfImp(BlockT *HeadBlock, BlockT *TrueBlock, 328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *FalseBlock); 329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int improveSimpleJumpintoIf(BlockT *HeadBlock, BlockT *TrueBlock, 330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *FalseBlock, BlockT **LandBlockPtr); 331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void showImproveSimpleJumpintoIf(BlockT *HeadBlock, BlockT *TrueBlock, 332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *FalseBlock, BlockT *LandBlock, 333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool Detail = false); 334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org PathToKind singlePathTo(BlockT *SrcBlock, BlockT *DstBlock, 335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool AllowSideEntry = true); 336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *singlePathEnd(BlockT *srcBlock, BlockT *DstBlock, 337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool AllowSideEntry = true); 338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int cloneOnSideEntryTo(BlockT *PreBlock, BlockT *SrcBlock, BlockT *DstBlock); 339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void mergeSerialBlock(BlockT *DstBlock, BlockT *srcBlock); 340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void mergeIfthenelseBlock(InstrT *BranchInstr, BlockT *CurBlock, 342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *TrueBlock, BlockT *FalseBlock, 343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *LandBlock); 344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void mergeLooplandBlock(BlockT *DstBlock, LoopLandInfo *LoopLand); 345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void mergeLoopbreakBlock(BlockT *ExitingBlock, BlockT *ExitBlock, 346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *ExitLandBlock, RegiT SetReg); 347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void settleLoopcontBlock(BlockT *ContingBlock, BlockT *ContBlock, 348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RegiT SetReg); 349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *relocateLoopcontBlock(LoopT *ParentLoopRep, LoopT *LoopRep, 350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org std::set<BlockT*> &ExitBlockSet, 351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *ExitLandBlk); 352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *addLoopEndbranchBlock(LoopT *LoopRep, 353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockTSmallerVector &ExitingBlocks, 354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockTSmallerVector &ExitBlocks); 355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *normalizeInfiniteLoopExit(LoopT *LoopRep); 356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void removeUnconditionalBranch(BlockT *SrcBlock); 357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void removeRedundantConditionalBranch(BlockT *SrcBlock); 358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void addDummyExitBlock(SmallVector<BlockT *, DEFAULT_VEC_SLOTS> &RetBlocks); 359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void removeSuccessor(BlockT *SrcBlock); 361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *cloneBlockForPredecessor(BlockT *CurBlock, BlockT *PredBlock); 362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *exitingBlock2ExitBlock (LoopT *LoopRep, BlockT *exitingBlock); 363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void migrateInstruction(BlockT *SrcBlock, BlockT *DstBlock, 365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org InstrIterator InsertPos); 366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void recordSccnum(BlockT *SrcBlock, int SCCNum); 368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int getSCCNum(BlockT *srcBlk); 369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void retireBlock(BlockT *DstBlock, BlockT *SrcBlock); 371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool isRetiredBlock(BlockT *SrcBlock); 372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool isActiveLoophead(BlockT *CurBlock); 373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool needMigrateBlock(BlockT *Block); 374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *recordLoopLandBlock(LoopT *LoopRep, BlockT *LandBlock, 376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockTSmallerVector &exitBlocks, 377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org std::set<BlockT*> &ExitBlockSet); 378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void setLoopLandBlock(LoopT *LoopRep, BlockT *Block = NULL); 379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *getLoopLandBlock(LoopT *LoopRep); 380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LoopLandInfo *getLoopLandInfo(LoopT *LoopRep); 381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void addLoopBreakOnReg(LoopT *LoopRep, RegiT RegNum); 383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void addLoopContOnReg(LoopT *LoopRep, RegiT RegNum); 384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void addLoopBreakInitReg(LoopT *LoopRep, RegiT RegNum); 385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void addLoopContInitReg(LoopT *LoopRep, RegiT RegNum); 386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void addLoopEndbranchInitReg(LoopT *LoopRep, RegiT RegNum); 387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool hasBackEdge(BlockT *curBlock); 389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned getLoopDepth (LoopT *LoopRep); 390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int countActiveBlock( 391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org typename SmallVector<BlockT *, DEFAULT_VEC_SLOTS>::const_iterator IterStart, 392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org typename SmallVector<BlockT *, DEFAULT_VEC_SLOTS>::const_iterator IterEnd); 393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *findNearestCommonPostDom(std::set<BlockT *>&); 394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *findNearestCommonPostDom(BlockT *Block1, BlockT *Block2); 395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgprivate: 397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org DomTreeT *domTree; 398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org PostDomTreeT *postDomTree; 399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LoopInfoT *loopInfo; 400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org PassT *passRep; 401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org FuncT *funcRep; 402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockInfoMap blockInfoMap; 404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LoopLandInfoMap loopLandInfoMap; 405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SmallVector<BlockT *, DEFAULT_VEC_SLOTS> orderedBlks; 406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const AMDGPURegisterInfo *TRI; 407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; //template class CFGStructurizer 409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT> CFGStructurizer<PassT>::CFGStructurizer() 411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org : domTree(NULL), postDomTree(NULL), loopInfo(NULL) { 412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT> CFGStructurizer<PassT>::~CFGStructurizer() { 415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (typename BlockInfoMap::iterator I = blockInfoMap.begin(), 416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org E = blockInfoMap.end(); I != E; ++I) { 417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org delete I->second; 418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT> 422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool CFGStructurizer<PassT>::prepare(FuncT &func, PassT &pass, 423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const AMDGPURegisterInfo * tri) { 424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org passRep = &pass; 425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org funcRep = &func; 426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org TRI = tri; 427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool changed = false; 429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //func.RenumberBlocks(); 430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //to do, if not reducible flow graph, make it so ??? 432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUGME) { 434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "AMDGPUCFGStructurizer::prepare\n"; 435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //func.viewCFG(); 436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //func.viewCFGOnly(); 437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //func.dump(); 438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //FIXME: gcc complains on this. 441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //domTree = &pass.getAnalysis<DomTreeT>(); 442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //domTree = CFGTraits::getDominatorTree(pass); 443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //if (DEBUGME) { 444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // domTree->print(errs()); 445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //} 446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //FIXME: gcc complains on this. 448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //domTree = &pass.getAnalysis<DomTreeT>(); 449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //postDomTree = CFGTraits::getPostDominatorTree(pass); 450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //if (DEBUGME) { 451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // postDomTree->print(errs()); 452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //} 453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //FIXME: gcc complains on this. 455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //loopInfo = &pass.getAnalysis<LoopInfoT>(); 456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org loopInfo = CFGTraits::getLoopInfo(pass); 457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUGME) { 458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "LoopInfo:\n"; 459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org PrintLoopinfo(*loopInfo, errs()); 460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org orderBlocks(); 463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUGME) { 464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "Ordered blocks:\n"; 465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org printOrderedBlocks(errs()); 466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SmallVector<BlockT *, DEFAULT_VEC_SLOTS> retBlks; 469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (typename LoopInfoT::iterator iter = loopInfo->begin(), 471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org iterEnd = loopInfo->end(); 472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org iter != iterEnd; ++iter) { 473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LoopT* loopRep = (*iter); 474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockTSmallerVector exitingBlks; 475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org loopRep->getExitingBlocks(exitingBlks); 476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (exitingBlks.size() == 0) { 478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT* dummyExitBlk = normalizeInfiniteLoopExit(loopRep); 479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (dummyExitBlk != NULL) 480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org retBlks.push_back(dummyExitBlk); 481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // Remove unconditional branch instr. 485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // Add dummy exit block iff there are multiple returns. 486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (typename SmallVector<BlockT *, DEFAULT_VEC_SLOTS>::const_iterator 488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org iterBlk = orderedBlks.begin(), iterEndBlk = orderedBlks.end(); 489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org iterBlk != iterEndBlk; 490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ++iterBlk) { 491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *curBlk = *iterBlk; 492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org removeUnconditionalBranch(curBlk); 493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org removeRedundantConditionalBranch(curBlk); 494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (CFGTraits::isReturnBlock(curBlk)) { 495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org retBlks.push_back(curBlk); 496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(curBlk->succ_size() <= 2); 498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //assert(curBlk->size() > 0); 499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //removeEmptyBlock(curBlk) ?? 500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } //for 501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (retBlks.size() >= 2) { 503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org addDummyExitBlock(retBlks); 504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org changed = true; 505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return changed; 508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //CFGStructurizer::prepare 509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT> 511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool CFGStructurizer<PassT>::run(FuncT &func, PassT &pass, 512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const AMDGPURegisterInfo * tri) { 513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org passRep = &pass; 514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org funcRep = &func; 515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org TRI = tri; 516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //func.RenumberBlocks(); 518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //Assume reducible CFG... 520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUGME) { 521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "AMDGPUCFGStructurizer::run\n"; 522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //errs() << func.getFunction()->getNameStr() << "\n"; 523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org func.viewCFG(); 524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //func.viewCFGOnly(); 525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //func.dump(); 526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if 1 529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //FIXME: gcc complains on this. 530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //domTree = &pass.getAnalysis<DomTreeT>(); 531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org domTree = CFGTraits::getDominatorTree(pass); 532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUGME) { 533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org domTree->print(errs(), (const llvm::Module*)0); 534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //FIXME: gcc complains on this. 538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //domTree = &pass.getAnalysis<DomTreeT>(); 539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org postDomTree = CFGTraits::getPostDominatorTree(pass); 540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUGME) { 541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org postDomTree->print(errs()); 542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //FIXME: gcc complains on this. 545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //loopInfo = &pass.getAnalysis<LoopInfoT>(); 546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org loopInfo = CFGTraits::getLoopInfo(pass); 547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUGME) { 548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "LoopInfo:\n"; 549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org PrintLoopinfo(*loopInfo, errs()); 550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org orderBlocks(); 553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//#define STRESSTEST 554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef STRESSTEST 555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //Use the worse block ordering to test the algorithm. 556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ReverseVector(orderedBlks); 557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUGME) { 560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "Ordered blocks:\n"; 561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org printOrderedBlocks(errs()); 562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int numIter = 0; 564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool finish = false; 565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *curBlk; 566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool makeProgress = false; 567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int numRemainedBlk = countActiveBlock(orderedBlks.begin(), 568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org orderedBlks.end()); 569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org do { 571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ++numIter; 572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUGME) { 573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "numIter = " << numIter 574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org << ", numRemaintedBlk = " << numRemainedBlk << "\n"; 575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org typename SmallVector<BlockT *, DEFAULT_VEC_SLOTS>::const_iterator 578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org iterBlk = orderedBlks.begin(); 579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org typename SmallVector<BlockT *, DEFAULT_VEC_SLOTS>::const_iterator 580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org iterBlkEnd = orderedBlks.end(); 581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org typename SmallVector<BlockT *, DEFAULT_VEC_SLOTS>::const_iterator 583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sccBeginIter = iterBlk; 584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *sccBeginBlk = NULL; 585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int sccNumBlk = 0; // The number of active blocks, init to a 586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // maximum possible number. 587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int sccNumIter; // Number of iteration in this SCC. 588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org while (iterBlk != iterBlkEnd) { 590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org curBlk = *iterBlk; 591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (sccBeginBlk == NULL) { 593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sccBeginIter = iterBlk; 594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sccBeginBlk = curBlk; 595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sccNumIter = 0; 596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sccNumBlk = numRemainedBlk; // Init to maximum possible number. 597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUGME) { 598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "start processing SCC" << getSCCNum(sccBeginBlk); 599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "\n"; 600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!isRetiredBlock(curBlk)) { 604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org patternMatch(curBlk); 605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ++iterBlk; 608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool contNextScc = true; 610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (iterBlk == iterBlkEnd 611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org || getSCCNum(sccBeginBlk) != getSCCNum(*iterBlk)) { 612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // Just finish one scc. 613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ++sccNumIter; 614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int sccRemainedNumBlk = countActiveBlock(sccBeginIter, iterBlk); 615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (sccRemainedNumBlk != 1 && sccRemainedNumBlk >= sccNumBlk) { 616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUGME) { 617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "Can't reduce SCC " << getSCCNum(curBlk) 618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org << ", sccNumIter = " << sccNumIter; 619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "doesn't make any progress\n"; 620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org contNextScc = true; 622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (sccRemainedNumBlk != 1 && sccRemainedNumBlk < sccNumBlk) { 623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sccNumBlk = sccRemainedNumBlk; 624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org iterBlk = sccBeginIter; 625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org contNextScc = false; 626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUGME) { 627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "repeat processing SCC" << getSCCNum(curBlk) 628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org << "sccNumIter = " << sccNumIter << "\n"; 629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org func.viewCFG(); 630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //func.viewCFGOnly(); 631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // Finish the current scc. 634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org contNextScc = true; 635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // Continue on next component in the current scc. 638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org contNextScc = false; 639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (contNextScc) { 642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sccBeginBlk = NULL; 643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } //while, "one iteration" over the function. 645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *entryBlk = FuncGTraits::nodes_begin(&func); 647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (entryBlk->succ_size() == 0) { 648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org finish = true; 649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUGME) { 650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "Reduce to one block\n"; 651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int newnumRemainedBlk 654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org = countActiveBlock(orderedBlks.begin(), orderedBlks.end()); 655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // consider cloned blocks ?? 656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (newnumRemainedBlk == 1 || newnumRemainedBlk < numRemainedBlk) { 657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org makeProgress = true; 658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org numRemainedBlk = newnumRemainedBlk; 659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org makeProgress = false; 661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUGME) { 662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "No progress\n"; 663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } while (!finish && makeProgress); 667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // Misc wrap up to maintain the consistency of the Function representation. 669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org CFGTraits::wrapup(FuncGTraits::nodes_begin(&func)); 670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // Detach retired Block, release memory. 672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (typename BlockInfoMap::iterator iterMap = blockInfoMap.begin(), 673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org iterEndMap = blockInfoMap.end(); iterMap != iterEndMap; ++iterMap) { 674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ((*iterMap).second && (*iterMap).second->isRetired) { 675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(((*iterMap).first)->getNumber() != -1); 676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUGME) { 677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "Erase BB" << ((*iterMap).first)->getNumber() << "\n"; 678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (*iterMap).first->eraseFromParent(); //Remove from the parent Function. 680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org delete (*iterMap).second; 682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org blockInfoMap.clear(); 684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // clear loopLandInfoMap 686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (typename LoopLandInfoMap::iterator iterMap = loopLandInfoMap.begin(), 687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org iterEndMap = loopLandInfoMap.end(); iterMap != iterEndMap; ++iterMap) { 688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org delete (*iterMap).second; 689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org loopLandInfoMap.clear(); 691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUGME) { 693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org func.viewCFG(); 694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //func.dump(); 695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!finish) { 698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(!"IRREDUCIBL_CF"); 699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return true; 702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //CFGStructurizer::run 703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// Print the ordered Blocks. 705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// 706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT> 707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid CFGStructurizer<PassT>::printOrderedBlocks(llvm::raw_ostream &os) { 708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org size_t i = 0; 709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (typename SmallVector<BlockT *, DEFAULT_VEC_SLOTS>::const_iterator 710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org iterBlk = orderedBlks.begin(), iterBlkEnd = orderedBlks.end(); 711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org iterBlk != iterBlkEnd; 712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ++iterBlk, ++i) { 713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org os << "BB" << (*iterBlk)->getNumber(); 714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org os << "(" << getSCCNum(*iterBlk) << "," << (*iterBlk)->size() << ")"; 715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (i != 0 && i % 10 == 0) { 716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org os << "\n"; 717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org os << " "; 719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //printOrderedBlocks 722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// Compute the reversed DFS post order of Blocks 724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// 725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT> void CFGStructurizer<PassT>::orderBlocks() { 726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int sccNum = 0; 727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *bb; 728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (scc_iterator<FuncT *> sccIter = scc_begin(funcRep), 729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sccEnd = scc_end(funcRep); sccIter != sccEnd; ++sccIter, ++sccNum) { 730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org std::vector<BlockT *> &sccNext = *sccIter; 731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (typename std::vector<BlockT *>::const_iterator 732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org blockIter = sccNext.begin(), blockEnd = sccNext.end(); 733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org blockIter != blockEnd; ++blockIter) { 734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bb = *blockIter; 735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org orderedBlks.push_back(bb); 736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org recordSccnum(bb, sccNum); 737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //walk through all the block in func to check for unreachable 741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (BlockIterator blockIter1 = FuncGTraits::nodes_begin(funcRep), 742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org blockEnd1 = FuncGTraits::nodes_end(funcRep); 743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org blockIter1 != blockEnd1; ++blockIter1) { 744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *bb = &(*blockIter1); 745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sccNum = getSCCNum(bb); 746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (sccNum == INVALIDSCCNUM) { 747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "unreachable block BB" << bb->getNumber() << "\n"; 748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } //end of for 750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //orderBlocks 751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT> int CFGStructurizer<PassT>::patternMatch(BlockT *curBlk) { 753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int numMatch = 0; 754f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int curMatch; 755f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 756f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUGME) { 757f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "Begin patternMatch BB" << curBlk->getNumber() << "\n"; 758f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 759f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 760f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org while ((curMatch = patternMatchGroup(curBlk)) > 0) { 761f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org numMatch += curMatch; 762f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 763f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 764f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUGME) { 765f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "End patternMatch BB" << curBlk->getNumber() 766f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org << ", numMatch = " << numMatch << "\n"; 767f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 768f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 769f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return numMatch; 770f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //patternMatch 771f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 772f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT> 773f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgint CFGStructurizer<PassT>::patternMatchGroup(BlockT *curBlk) { 774f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int numMatch = 0; 775f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org numMatch += serialPatternMatch(curBlk); 776f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org numMatch += ifPatternMatch(curBlk); 777f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //numMatch += switchPatternMatch(curBlk); 778f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org numMatch += loopendPatternMatch(curBlk); 779f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org numMatch += loopPatternMatch(curBlk); 780f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return numMatch; 781f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}//patternMatchGroup 782f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 783f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT> 784f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgint CFGStructurizer<PassT>::serialPatternMatch(BlockT *curBlk) { 785f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (curBlk->succ_size() != 1) { 786f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 0; 787f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 788f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 789f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *childBlk = *curBlk->succ_begin(); 790f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (childBlk->pred_size() != 1 || isActiveLoophead(childBlk)) { 791f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 0; 792f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 793f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 794f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mergeSerialBlock(curBlk, childBlk); 795f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ++numSerialPatternMatch; 796f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 1; 797f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //serialPatternMatch 798f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 799f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT> 800f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgint CFGStructurizer<PassT>::ifPatternMatch(BlockT *curBlk) { 801f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //two edges 802f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (curBlk->succ_size() != 2) { 803f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 0; 804f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 805f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 806f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (hasBackEdge(curBlk)) { 807f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 0; 808f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 809f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 810f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org InstrT *branchInstr = CFGTraits::getNormalBlockBranchInstr(curBlk); 811f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (branchInstr == NULL) { 812f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 0; 813f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 814f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 815f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(CFGTraits::isCondBranch(branchInstr)); 816f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 817f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *trueBlk = CFGTraits::getTrueBranch(branchInstr); 818f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *falseBlk = CFGTraits::getFalseBranch(curBlk, branchInstr); 819f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *landBlk; 820f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int cloned = 0; 821f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 822f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // TODO: Simplify 823f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (trueBlk->succ_size() == 1 && falseBlk->succ_size() == 1 824f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && *trueBlk->succ_begin() == *falseBlk->succ_begin()) { 825f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org landBlk = *trueBlk->succ_begin(); 826f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (trueBlk->succ_size() == 0 && falseBlk->succ_size() == 0) { 827f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org landBlk = NULL; 828f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (trueBlk->succ_size() == 1 && *trueBlk->succ_begin() == falseBlk) { 829f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org landBlk = falseBlk; 830f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org falseBlk = NULL; 831f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (falseBlk->succ_size() == 1 832f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && *falseBlk->succ_begin() == trueBlk) { 833f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org landBlk = trueBlk; 834f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org trueBlk = NULL; 835f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (falseBlk->succ_size() == 1 836f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && isSameloopDetachedContbreak(trueBlk, falseBlk)) { 837f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org landBlk = *falseBlk->succ_begin(); 838f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (trueBlk->succ_size() == 1 839f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && isSameloopDetachedContbreak(falseBlk, trueBlk)) { 840f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org landBlk = *trueBlk->succ_begin(); 841f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 842f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return handleJumpintoIf(curBlk, trueBlk, falseBlk); 843f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 844f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 845f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // improveSimpleJumpinfoIf can handle the case where landBlk == NULL but the 846f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // new BB created for landBlk==NULL may introduce new challenge to the 847f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // reduction process. 848f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (landBlk != NULL && 849f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ((trueBlk && trueBlk->pred_size() > 1) 850f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org || (falseBlk && falseBlk->pred_size() > 1))) { 851f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cloned += improveSimpleJumpintoIf(curBlk, trueBlk, falseBlk, &landBlk); 852f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 853f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 854f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (trueBlk && trueBlk->pred_size() > 1) { 855f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org trueBlk = cloneBlockForPredecessor(trueBlk, curBlk); 856f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ++cloned; 857f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 858f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 859f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (falseBlk && falseBlk->pred_size() > 1) { 860f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org falseBlk = cloneBlockForPredecessor(falseBlk, curBlk); 861f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ++cloned; 862f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 863f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 864f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mergeIfthenelseBlock(branchInstr, curBlk, trueBlk, falseBlk, landBlk); 865f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 866f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ++numIfPatternMatch; 867f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 868f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org numClonedBlock += cloned; 869f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 870f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 1 + cloned; 871f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //ifPatternMatch 872f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 873f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT> 874f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgint CFGStructurizer<PassT>::switchPatternMatch(BlockT *curBlk) { 875f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 0; 876f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //switchPatternMatch 877f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 878f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT> 879f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgint CFGStructurizer<PassT>::loopendPatternMatch(BlockT *curBlk) { 880f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LoopT *loopRep = loopInfo->getLoopFor(curBlk); 881f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org typename std::vector<LoopT *> nestedLoops; 882f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org while (loopRep) { 883f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org nestedLoops.push_back(loopRep); 884f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org loopRep = loopRep->getParentLoop(); 885f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 886f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 887f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (nestedLoops.size() == 0) { 888f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 0; 889f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 890f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 891f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // Process nested loop outside->inside, so "continue" to a outside loop won't 892f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // be mistaken as "break" of the current loop. 893f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int num = 0; 894f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (typename std::vector<LoopT *>::reverse_iterator 895f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org iter = nestedLoops.rbegin(), iterEnd = nestedLoops.rend(); 896f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org iter != iterEnd; ++iter) { 897f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org loopRep = *iter; 898f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 899f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (getLoopLandBlock(loopRep) != NULL) { 900f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org continue; 901f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 902f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 903f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *loopHeader = loopRep->getHeader(); 904f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 905f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int numBreak = loopbreakPatternMatch(loopRep, loopHeader); 906f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 907f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (numBreak == -1) { 908f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 909f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 910f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 911f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int numCont = loopcontPatternMatch(loopRep, loopHeader); 912f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org num += numBreak + numCont; 913f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 914f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 915f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return num; 916f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //loopendPatternMatch 917f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 918f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT> 919f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgint CFGStructurizer<PassT>::loopPatternMatch(BlockT *curBlk) { 920f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (curBlk->succ_size() != 0) { 921f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 0; 922f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 923f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 924f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int numLoop = 0; 925f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LoopT *loopRep = loopInfo->getLoopFor(curBlk); 926f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org while (loopRep && loopRep->getHeader() == curBlk) { 927f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LoopLandInfo *loopLand = getLoopLandInfo(loopRep); 928f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (loopLand) { 929f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *landBlk = loopLand->landBlk; 930f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(landBlk); 931f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!isRetiredBlock(landBlk)) { 932f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mergeLooplandBlock(curBlk, loopLand); 933f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ++numLoop; 934f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 935f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 936f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org loopRep = loopRep->getParentLoop(); 937f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 938f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 939f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org numLoopPatternMatch += numLoop; 940f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 941f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return numLoop; 942f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //loopPatternMatch 943f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 944f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT> 945f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgint CFGStructurizer<PassT>::loopbreakPatternMatch(LoopT *loopRep, 946f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *loopHeader) { 947f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockTSmallerVector exitingBlks; 948f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org loopRep->getExitingBlocks(exitingBlks); 949f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 950f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUGME) { 951f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "Loop has " << exitingBlks.size() << " exiting blocks\n"; 952f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 953f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 954f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (exitingBlks.size() == 0) { 955f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org setLoopLandBlock(loopRep); 956f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 0; 957f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 958f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 959f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // Compute the corresponding exitBlks and exit block set. 960f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockTSmallerVector exitBlks; 961f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org std::set<BlockT *> exitBlkSet; 962f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (typename BlockTSmallerVector::const_iterator iter = exitingBlks.begin(), 963f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org iterEnd = exitingBlks.end(); iter != iterEnd; ++iter) { 964f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *exitingBlk = *iter; 965f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *exitBlk = exitingBlock2ExitBlock(loopRep, exitingBlk); 966f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org exitBlks.push_back(exitBlk); 967f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org exitBlkSet.insert(exitBlk); //non-duplicate insert 968f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 969f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 970f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(exitBlkSet.size() > 0); 971f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(exitBlks.size() == exitingBlks.size()); 972f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 973f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUGME) { 974f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "Loop has " << exitBlkSet.size() << " exit blocks\n"; 975f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 976f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 977f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // Find exitLandBlk. 978f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *exitLandBlk = NULL; 979f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int numCloned = 0; 980f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int numSerial = 0; 981f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 982f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (exitBlkSet.size() == 1) 983f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 984f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org exitLandBlk = *exitBlkSet.begin(); 985f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 986f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org exitLandBlk = findNearestCommonPostDom(exitBlkSet); 987f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 988f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (exitLandBlk == NULL) { 989f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return -1; 990f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 991f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 992f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool allInPath = true; 993f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool allNotInPath = true; 994f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (typename std::set<BlockT*>::const_iterator 995f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org iter = exitBlkSet.begin(), 996f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org iterEnd = exitBlkSet.end(); 997f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org iter != iterEnd; ++iter) { 998f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *exitBlk = *iter; 999f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1000f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org PathToKind pathKind = singlePathTo(exitBlk, exitLandBlk, true); 1001f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUGME) { 1002f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "BB" << exitBlk->getNumber() 1003f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org << " to BB" << exitLandBlk->getNumber() << " PathToKind=" 1004f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org << pathKind << "\n"; 1005f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1006f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1007f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org allInPath = allInPath && (pathKind == SinglePath_InPath); 1008f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org allNotInPath = allNotInPath && (pathKind == SinglePath_NotInPath); 1009f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1010f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!allInPath && !allNotInPath) { 1011f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUGME) { 1012f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "singlePath check fail\n"; 1013f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1014f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return -1; 1015f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1016f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } // check all exit blocks 1017f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1018f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (allNotInPath) { 1019f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if 1 1020f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1021f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // TODO: Simplify, maybe separate function? 1022f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //funcRep->viewCFG(); 1023f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LoopT *parentLoopRep = loopRep->getParentLoop(); 1024f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *parentLoopHeader = NULL; 1025f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (parentLoopRep) 1026f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org parentLoopHeader = parentLoopRep->getHeader(); 1027f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1028f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (exitLandBlk == parentLoopHeader && 1029f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (exitLandBlk = relocateLoopcontBlock(parentLoopRep, 1030f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org loopRep, 1031f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org exitBlkSet, 1032f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org exitLandBlk)) != NULL) { 1033f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUGME) { 1034f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "relocateLoopcontBlock success\n"; 1035f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1036f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if ((exitLandBlk = addLoopEndbranchBlock(loopRep, 1037f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org exitingBlks, 1038f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org exitBlks)) != NULL) { 1039f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUGME) { 1040f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "insertEndbranchBlock success\n"; 1041f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1042f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 1043f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUGME) { 1044f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "loop exit fail\n"; 1045f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1046f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return -1; 1047f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1048f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#else 1049f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return -1; 1050f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 1051f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1052f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1053f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // Handle side entry to exit path. 1054f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org exitBlks.clear(); 1055f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org exitBlkSet.clear(); 1056f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (typename BlockTSmallerVector::iterator iterExiting = 1057f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org exitingBlks.begin(), 1058f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org iterExitingEnd = exitingBlks.end(); 1059f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org iterExiting != iterExitingEnd; ++iterExiting) { 1060f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *exitingBlk = *iterExiting; 1061f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *exitBlk = exitingBlock2ExitBlock(loopRep, exitingBlk); 1062f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *newExitBlk = exitBlk; 1063f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1064f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (exitBlk != exitLandBlk && exitBlk->pred_size() > 1) { 1065f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org newExitBlk = cloneBlockForPredecessor(exitBlk, exitingBlk); 1066f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ++numCloned; 1067f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1068f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1069f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org numCloned += cloneOnSideEntryTo(exitingBlk, newExitBlk, exitLandBlk); 1070f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1071f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org exitBlks.push_back(newExitBlk); 1072f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org exitBlkSet.insert(newExitBlk); 1073f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1074f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1075f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (typename BlockTSmallerVector::iterator iterExit = exitBlks.begin(), 1076f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org iterExitEnd = exitBlks.end(); 1077f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org iterExit != iterExitEnd; ++iterExit) { 1078f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *exitBlk = *iterExit; 1079f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org numSerial += serialPatternMatch(exitBlk); 1080f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1081f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1082f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (typename BlockTSmallerVector::iterator iterExit = exitBlks.begin(), 1083f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org iterExitEnd = exitBlks.end(); 1084f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org iterExit != iterExitEnd; ++iterExit) { 1085f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *exitBlk = *iterExit; 1086f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (exitBlk->pred_size() > 1) { 1087f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (exitBlk != exitLandBlk) { 1088f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return -1; 1089f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1090f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 1091f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (exitBlk != exitLandBlk && 1092f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (exitBlk->succ_size() != 1 || 1093f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *exitBlk->succ_begin() != exitLandBlk)) { 1094f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return -1; 1095f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1096f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1097f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1098f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } // else 1099f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // LoopT *exitLandLoop = loopInfo->getLoopFor(exitLandBlk); 1101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org exitLandBlk = recordLoopLandBlock(loopRep, exitLandBlk, exitBlks, exitBlkSet); 1102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // Fold break into the breaking block. Leverage across level breaks. 1104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(exitingBlks.size() == exitBlks.size()); 1105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (typename BlockTSmallerVector::const_iterator iterExit = exitBlks.begin(), 1106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org iterExiting = exitingBlks.begin(), iterExitEnd = exitBlks.end(); 1107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org iterExit != iterExitEnd; ++iterExit, ++iterExiting) { 1108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *exitBlk = *iterExit; 1109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *exitingBlk = *iterExiting; 1110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(exitBlk->pred_size() == 1 || exitBlk == exitLandBlk); 1111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LoopT *exitingLoop = loopInfo->getLoopFor(exitingBlk); 1112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org handleLoopbreak(exitingBlk, exitingLoop, exitBlk, loopRep, exitLandBlk); 1113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int numBreak = static_cast<int>(exitingBlks.size()); 1116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org numLoopbreakPatternMatch += numBreak; 1117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org numClonedBlock += numCloned; 1118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return numBreak + numSerial + numCloned; 1119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //loopbreakPatternMatch 1120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT> 1122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgint CFGStructurizer<PassT>::loopcontPatternMatch(LoopT *loopRep, 1123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *loopHeader) { 1124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int numCont = 0; 1125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SmallVector<BlockT *, DEFAULT_VEC_SLOTS> contBlk; 1126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (typename InvBlockGTraits::ChildIteratorType iter = 1127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org InvBlockGTraits::child_begin(loopHeader), 1128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org iterEnd = InvBlockGTraits::child_end(loopHeader); 1129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org iter != iterEnd; ++iter) { 1130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *curBlk = *iter; 1131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (loopRep->contains(curBlk)) { 1132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org handleLoopcontBlock(curBlk, loopInfo->getLoopFor(curBlk), 1133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org loopHeader, loopRep); 1134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org contBlk.push_back(curBlk); 1135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ++numCont; 1136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (typename SmallVector<BlockT *, DEFAULT_VEC_SLOTS>::iterator 1140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org iter = contBlk.begin(), iterEnd = contBlk.end(); 1141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org iter != iterEnd; ++iter) { 1142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (*iter)->removeSuccessor(loopHeader); 1143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org numLoopcontPatternMatch += numCont; 1146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return numCont; 1148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //loopcontPatternMatch 1149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT> 1152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool CFGStructurizer<PassT>::isSameloopDetachedContbreak(BlockT *src1Blk, 1153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *src2Blk) { 1154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // return true iff src1Blk->succ_size() == 0 && src1Blk and src2Blk are in the 1155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // same loop with LoopLandInfo without explicitly keeping track of 1156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // loopContBlks and loopBreakBlks, this is a method to get the information. 1157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // 1158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (src1Blk->succ_size() == 0) { 1159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LoopT *loopRep = loopInfo->getLoopFor(src1Blk); 1160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (loopRep != NULL && loopRep == loopInfo->getLoopFor(src2Blk)) { 1161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LoopLandInfo *&theEntry = loopLandInfoMap[loopRep]; 1162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (theEntry != NULL) { 1163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUGME) { 1164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "isLoopContBreakBlock yes src1 = BB" 1165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org << src1Blk->getNumber() 1166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org << " src2 = BB" << src2Blk->getNumber() << "\n"; 1167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return true; 1169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return false; 1173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //isSameloopDetachedContbreak 1174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT> 1176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgint CFGStructurizer<PassT>::handleJumpintoIf(BlockT *headBlk, 1177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *trueBlk, 1178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *falseBlk) { 1179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int num = handleJumpintoIfImp(headBlk, trueBlk, falseBlk); 1180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (num == 0) { 1181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUGME) { 1182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "handleJumpintoIf swap trueBlk and FalseBlk" << "\n"; 1183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org num = handleJumpintoIfImp(headBlk, falseBlk, trueBlk); 1185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return num; 1187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT> 1190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgint CFGStructurizer<PassT>::handleJumpintoIfImp(BlockT *headBlk, 1191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *trueBlk, 1192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *falseBlk) { 1193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int num = 0; 1194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *downBlk; 1195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //trueBlk could be the common post dominator 1197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org downBlk = trueBlk; 1198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUGME) { 1200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "handleJumpintoIfImp head = BB" << headBlk->getNumber() 1201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org << " true = BB" << trueBlk->getNumber() 1202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org << ", numSucc=" << trueBlk->succ_size() 1203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org << " false = BB" << falseBlk->getNumber() << "\n"; 1204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org while (downBlk) { 1207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUGME) { 1208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "check down = BB" << downBlk->getNumber(); 1209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (//postDomTree->dominates(downBlk, falseBlk) && 1212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org singlePathTo(falseBlk, downBlk) == SinglePath_InPath) { 1213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUGME) { 1214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << " working\n"; 1215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org num += cloneOnSideEntryTo(headBlk, trueBlk, downBlk); 1218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org num += cloneOnSideEntryTo(headBlk, falseBlk, downBlk); 1219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org numClonedBlock += num; 1221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org num += serialPatternMatch(*headBlk->succ_begin()); 1222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org num += serialPatternMatch(*(++headBlk->succ_begin())); 1223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org num += ifPatternMatch(headBlk); 1224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(num > 0); // 1225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUGME) { 1229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << " not working\n"; 1230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org downBlk = (downBlk->succ_size() == 1) ? (*downBlk->succ_begin()) : NULL; 1232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } // walk down the postDomTree 1233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return num; 1235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //handleJumpintoIf 1236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT> 1238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid CFGStructurizer<PassT>::showImproveSimpleJumpintoIf(BlockT *headBlk, 1239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *trueBlk, 1240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *falseBlk, 1241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *landBlk, 1242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool detail) { 1243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "head = BB" << headBlk->getNumber() 1244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org << " size = " << headBlk->size(); 1245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (detail) { 1246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "\n"; 1247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org headBlk->print(errs()); 1248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "\n"; 1249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (trueBlk) { 1252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << ", true = BB" << trueBlk->getNumber() << " size = " 1253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org << trueBlk->size() << " numPred = " << trueBlk->pred_size(); 1254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (detail) { 1255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "\n"; 1256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org trueBlk->print(errs()); 1257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "\n"; 1258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (falseBlk) { 1261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << ", false = BB" << falseBlk->getNumber() << " size = " 1262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org << falseBlk->size() << " numPred = " << falseBlk->pred_size(); 1263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (detail) { 1264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "\n"; 1265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org falseBlk->print(errs()); 1266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "\n"; 1267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (landBlk) { 1270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << ", land = BB" << landBlk->getNumber() << " size = " 1271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org << landBlk->size() << " numPred = " << landBlk->pred_size(); 1272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (detail) { 1273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "\n"; 1274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org landBlk->print(errs()); 1275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "\n"; 1276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "\n"; 1280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //showImproveSimpleJumpintoIf 1281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT> 1283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgint CFGStructurizer<PassT>::improveSimpleJumpintoIf(BlockT *headBlk, 1284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *trueBlk, 1285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *falseBlk, 1286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT **plandBlk) { 1287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool migrateTrue = false; 1288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool migrateFalse = false; 1289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *landBlk = *plandBlk; 1291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert((trueBlk == NULL || trueBlk->succ_size() <= 1) 1293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && (falseBlk == NULL || falseBlk->succ_size() <= 1)); 1294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (trueBlk == falseBlk) { 1296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 0; 1297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if 0 1300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUGME) { 1301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "improveSimpleJumpintoIf: "; 1302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org showImproveSimpleJumpintoIf(headBlk, trueBlk, falseBlk, landBlk, 0); 1303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 1305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // unsigned landPredSize = landBlk ? landBlk->pred_size() : 0; 1307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // May consider the # landBlk->pred_size() as it represents the number of 1308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // assignment initReg = .. needed to insert. 1309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org migrateTrue = needMigrateBlock(trueBlk); 1310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org migrateFalse = needMigrateBlock(falseBlk); 1311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!migrateTrue && !migrateFalse) { 1313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 0; 1314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // If we need to migrate either trueBlk and falseBlk, migrate the rest that 1317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // have more than one predecessors. without doing this, its predecessor 1318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // rather than headBlk will have undefined value in initReg. 1319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!migrateTrue && trueBlk && trueBlk->pred_size() > 1) { 1320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org migrateTrue = true; 1321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!migrateFalse && falseBlk && falseBlk->pred_size() > 1) { 1323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org migrateFalse = true; 1324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUGME) { 1327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "before improveSimpleJumpintoIf: "; 1328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org showImproveSimpleJumpintoIf(headBlk, trueBlk, falseBlk, landBlk, 0); 1329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //showImproveSimpleJumpintoIf(headBlk, trueBlk, falseBlk, landBlk, 1); 1330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // org: headBlk => if () {trueBlk} else {falseBlk} => landBlk 1333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // 1334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // new: headBlk => if () {initReg = 1; org trueBlk branch} else 1335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // {initReg = 0; org falseBlk branch } 1336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // => landBlk => if (initReg) {org trueBlk} else {org falseBlk} 1337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // => org landBlk 1338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // if landBlk->pred_size() > 2, put the about if-else inside 1339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // if (initReg !=2) {...} 1340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // 1341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // add initReg = initVal to headBlk 1342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const TargetRegisterClass * I32RC = TRI->getCFGStructurizerRegClass(MVT::i32); 1344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned initReg = 1345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org funcRep->getRegInfo().createVirtualRegister(I32RC); 1346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!migrateTrue || !migrateFalse) { 1347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int initVal = migrateTrue ? 0 : 1; 1348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org CFGTraits::insertAssignInstrBefore(headBlk, passRep, initReg, initVal); 1349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int numNewBlk = 0; 1352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (landBlk == NULL) { 1354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org landBlk = funcRep->CreateMachineBasicBlock(); 1355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org funcRep->push_back(landBlk); //insert to function 1356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (trueBlk) { 1358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org trueBlk->addSuccessor(landBlk); 1359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 1360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org headBlk->addSuccessor(landBlk); 1361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (falseBlk) { 1364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org falseBlk->addSuccessor(landBlk); 1365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 1366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org headBlk->addSuccessor(landBlk); 1367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org numNewBlk ++; 1370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool landBlkHasOtherPred = (landBlk->pred_size() > 2); 1373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //insert AMDGPU::ENDIF to avoid special case "input landBlk == NULL" 1375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org typename BlockT::iterator insertPos = 1376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org CFGTraits::getInstrPos 1377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (landBlk, CFGTraits::insertInstrBefore(landBlk, AMDGPU::ENDIF, passRep)); 1378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (landBlkHasOtherPred) { 1380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned immReg = 1381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org funcRep->getRegInfo().createVirtualRegister(I32RC); 1382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org CFGTraits::insertAssignInstrBefore(insertPos, passRep, immReg, 2); 1383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned cmpResReg = 1384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org funcRep->getRegInfo().createVirtualRegister(I32RC); 1385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org CFGTraits::insertCompareInstrBefore(landBlk, insertPos, passRep, cmpResReg, 1387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org initReg, immReg); 1388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org CFGTraits::insertCondBranchBefore(landBlk, insertPos, 1389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org AMDGPU::IF_LOGICALZ_i32, passRep, 1390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cmpResReg, DebugLoc()); 1391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org CFGTraits::insertCondBranchBefore(landBlk, insertPos, AMDGPU::IF_LOGICALNZ_i32, 1394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org passRep, initReg, DebugLoc()); 1395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (migrateTrue) { 1397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org migrateInstruction(trueBlk, landBlk, insertPos); 1398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // need to uncondionally insert the assignment to ensure a path from its 1399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // predecessor rather than headBlk has valid value in initReg if 1400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // (initVal != 1). 1401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org CFGTraits::insertAssignInstrBefore(trueBlk, passRep, initReg, 1); 1402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org CFGTraits::insertInstrBefore(insertPos, AMDGPU::ELSE, passRep); 1404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (migrateFalse) { 1406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org migrateInstruction(falseBlk, landBlk, insertPos); 1407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // need to uncondionally insert the assignment to ensure a path from its 1408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // predecessor rather than headBlk has valid value in initReg if 1409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // (initVal != 0) 1410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org CFGTraits::insertAssignInstrBefore(falseBlk, passRep, initReg, 0); 1411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //CFGTraits::insertInstrBefore(insertPos, AMDGPU::ENDIF, passRep); 1413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (landBlkHasOtherPred) { 1415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // add endif 1416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org CFGTraits::insertInstrBefore(insertPos, AMDGPU::ENDIF, passRep); 1417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // put initReg = 2 to other predecessors of landBlk 1419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (typename BlockT::pred_iterator predIter = landBlk->pred_begin(), 1420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org predIterEnd = landBlk->pred_end(); predIter != predIterEnd; 1421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ++predIter) { 1422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *curBlk = *predIter; 1423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (curBlk != trueBlk && curBlk != falseBlk) { 1424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org CFGTraits::insertAssignInstrBefore(curBlk, passRep, initReg, 2); 1425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } //for 1427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUGME) { 1429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "result from improveSimpleJumpintoIf: "; 1430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org showImproveSimpleJumpintoIf(headBlk, trueBlk, falseBlk, landBlk, 0); 1431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //showImproveSimpleJumpintoIf(headBlk, trueBlk, falseBlk, landBlk, 1); 1432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // update landBlk 1435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *plandBlk = landBlk; 1436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return numNewBlk; 1438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //improveSimpleJumpintoIf 1439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT> 1441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid CFGStructurizer<PassT>::handleLoopbreak(BlockT *exitingBlk, 1442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LoopT *exitingLoop, 1443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *exitBlk, 1444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LoopT *exitLoop, 1445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *landBlk) { 1446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUGME) { 1447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "Trying to break loop-depth = " << getLoopDepth(exitLoop) 1448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org << " from loop-depth = " << getLoopDepth(exitingLoop) << "\n"; 1449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const TargetRegisterClass * I32RC = TRI->getCFGStructurizerRegClass(MVT::i32); 1451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RegiT initReg = INVALIDREGNUM; 1453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (exitingLoop != exitLoop) { 1454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org initReg = static_cast<int> 1455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (funcRep->getRegInfo().createVirtualRegister(I32RC)); 1456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(initReg != INVALIDREGNUM); 1457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org addLoopBreakInitReg(exitLoop, initReg); 1458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org while (exitingLoop != exitLoop && exitingLoop) { 1459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org addLoopBreakOnReg(exitingLoop, initReg); 1460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org exitingLoop = exitingLoop->getParentLoop(); 1461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(exitingLoop == exitLoop); 1463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mergeLoopbreakBlock(exitingBlk, exitBlk, landBlk, initReg); 1466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //handleLoopbreak 1468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT> 1470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid CFGStructurizer<PassT>::handleLoopcontBlock(BlockT *contingBlk, 1471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LoopT *contingLoop, 1472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *contBlk, 1473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LoopT *contLoop) { 1474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUGME) { 1475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "loopcontPattern cont = BB" << contingBlk->getNumber() 1476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org << " header = BB" << contBlk->getNumber() << "\n"; 1477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "Trying to continue loop-depth = " 1479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org << getLoopDepth(contLoop) 1480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org << " from loop-depth = " << getLoopDepth(contingLoop) << "\n"; 1481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RegiT initReg = INVALIDREGNUM; 1484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const TargetRegisterClass * I32RC = TRI->getCFGStructurizerRegClass(MVT::i32); 1485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (contingLoop != contLoop) { 1486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org initReg = static_cast<int> 1487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (funcRep->getRegInfo().createVirtualRegister(I32RC)); 1488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(initReg != INVALIDREGNUM); 1489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org addLoopContInitReg(contLoop, initReg); 1490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org while (contingLoop && contingLoop->getParentLoop() != contLoop) { 1491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org addLoopBreakOnReg(contingLoop, initReg); //not addLoopContOnReg 1492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org contingLoop = contingLoop->getParentLoop(); 1493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(contingLoop && contingLoop->getParentLoop() == contLoop); 1495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org addLoopContOnReg(contingLoop, initReg); 1496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org settleLoopcontBlock(contingBlk, contBlk, initReg); 1499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //contingBlk->removeSuccessor(loopHeader); 1500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //handleLoopcontBlock 1501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT> 1503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid CFGStructurizer<PassT>::mergeSerialBlock(BlockT *dstBlk, BlockT *srcBlk) { 1504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUGME) { 1505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "serialPattern BB" << dstBlk->getNumber() 1506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org << " <= BB" << srcBlk->getNumber() << "\n"; 1507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //removeUnconditionalBranch(dstBlk); 1509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dstBlk->splice(dstBlk->end(), srcBlk, FirstNonDebugInstr(srcBlk), srcBlk->end()); 1510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dstBlk->removeSuccessor(srcBlk); 1512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org CFGTraits::cloneSuccessorList(dstBlk, srcBlk); 1513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org removeSuccessor(srcBlk); 1515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org retireBlock(dstBlk, srcBlk); 1516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //mergeSerialBlock 1517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT> 1519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid CFGStructurizer<PassT>::mergeIfthenelseBlock(InstrT *branchInstr, 1520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *curBlk, 1521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *trueBlk, 1522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *falseBlk, 1523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *landBlk) { 1524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUGME) { 1525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "ifPattern BB" << curBlk->getNumber(); 1526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "{ "; 1527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (trueBlk) { 1528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "BB" << trueBlk->getNumber(); 1529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << " } else "; 1531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "{ "; 1532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (falseBlk) { 1533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "BB" << falseBlk->getNumber(); 1534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << " }\n "; 1536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "landBlock: "; 1537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (landBlk == NULL) { 1538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "NULL"; 1539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 1540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "BB" << landBlk->getNumber(); 1541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "\n"; 1543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int oldOpcode = branchInstr->getOpcode(); 1546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org DebugLoc branchDL = branchInstr->getDebugLoc(); 1547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// transform to 1549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// if cond 1550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// trueBlk 1551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// else 1552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// falseBlk 1553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// endif 1554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// landBlk 1555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org typename BlockT::iterator branchInstrPos = 1557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org CFGTraits::getInstrPos(curBlk, branchInstr); 1558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org CFGTraits::insertCondBranchBefore(branchInstrPos, 1559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org CFGTraits::getBranchNzeroOpcode(oldOpcode), 1560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org passRep, 1561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org branchDL); 1562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (trueBlk) { 1564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org curBlk->splice(branchInstrPos, trueBlk, FirstNonDebugInstr(trueBlk), trueBlk->end()); 1565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org curBlk->removeSuccessor(trueBlk); 1566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (landBlk && trueBlk->succ_size()!=0) { 1567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org trueBlk->removeSuccessor(landBlk); 1568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org retireBlock(curBlk, trueBlk); 1570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org CFGTraits::insertInstrBefore(branchInstrPos, AMDGPU::ELSE, passRep); 1572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (falseBlk) { 1574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org curBlk->splice(branchInstrPos, falseBlk, FirstNonDebugInstr(falseBlk), 1575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org falseBlk->end()); 1576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org curBlk->removeSuccessor(falseBlk); 1577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (landBlk && falseBlk->succ_size() != 0) { 1578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org falseBlk->removeSuccessor(landBlk); 1579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org retireBlock(curBlk, falseBlk); 1581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org CFGTraits::insertInstrBefore(branchInstrPos, AMDGPU::ENDIF, passRep); 1583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //curBlk->remove(branchInstrPos); 1585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org branchInstr->eraseFromParent(); 1586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (landBlk && trueBlk && falseBlk) { 1588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org curBlk->addSuccessor(landBlk); 1589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //mergeIfthenelseBlock 1592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT> 1594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid CFGStructurizer<PassT>::mergeLooplandBlock(BlockT *dstBlk, 1595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LoopLandInfo *loopLand) { 1596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *landBlk = loopLand->landBlk; 1597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUGME) { 1599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "loopPattern header = BB" << dstBlk->getNumber() 1600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org << " land = BB" << landBlk->getNumber() << "\n"; 1601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // Loop contInitRegs are init at the beginning of the loop. 1604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (typename std::set<RegiT>::const_iterator iter = 1605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org loopLand->contInitRegs.begin(), 1606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org iterEnd = loopLand->contInitRegs.end(); iter != iterEnd; ++iter) { 1607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org CFGTraits::insertAssignInstrBefore(dstBlk, passRep, *iter, 0); 1608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* we last inserterd the DebugLoc in the 1611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * BREAK_LOGICALZ_i32 or AMDGPU::BREAK_LOGICALNZ statement in the current dstBlk. 1612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * search for the DebugLoc in the that statement. 1613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * if not found, we have to insert the empty/default DebugLoc */ 1614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org InstrT *loopBreakInstr = CFGTraits::getLoopBreakInstr(dstBlk); 1615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org DebugLoc DLBreak = (loopBreakInstr) ? loopBreakInstr->getDebugLoc() : DebugLoc(); 1616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org CFGTraits::insertInstrBefore(dstBlk, AMDGPU::WHILELOOP, passRep, DLBreak); 1618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // Loop breakInitRegs are init before entering the loop. 1619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (typename std::set<RegiT>::const_iterator iter = 1620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org loopLand->breakInitRegs.begin(), 1621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org iterEnd = loopLand->breakInitRegs.end(); iter != iterEnd; ++iter) 1622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org CFGTraits::insertAssignInstrBefore(dstBlk, passRep, *iter, 0); 1624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // Loop endbranchInitRegs are init before entering the loop. 1626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (typename std::set<RegiT>::const_iterator iter = 1627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org loopLand->endbranchInitRegs.begin(), 1628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org iterEnd = loopLand->endbranchInitRegs.end(); iter != iterEnd; ++iter) { 1629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org CFGTraits::insertAssignInstrBefore(dstBlk, passRep, *iter, 0); 1630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* we last inserterd the DebugLoc in the continue statement in the current dstBlk 1633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * search for the DebugLoc in the continue statement. 1634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * if not found, we have to insert the empty/default DebugLoc */ 1635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org InstrT *continueInstr = CFGTraits::getContinueInstr(dstBlk); 1636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org DebugLoc DLContinue = (continueInstr) ? continueInstr->getDebugLoc() : DebugLoc(); 1637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org CFGTraits::insertInstrEnd(dstBlk, AMDGPU::ENDLOOP, passRep, DLContinue); 1639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // Loop breakOnRegs are check after the ENDLOOP: break the loop outside this 1640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // loop. 1641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (typename std::set<RegiT>::const_iterator iter = 1642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org loopLand->breakOnRegs.begin(), 1643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org iterEnd = loopLand->breakOnRegs.end(); iter != iterEnd; ++iter) { 1644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org CFGTraits::insertCondBranchEnd(dstBlk, AMDGPU::BREAK_LOGICALNZ_i32, passRep, 1645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *iter); 1646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // Loop contOnRegs are check after the ENDLOOP: cont the loop outside this 1649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // loop. 1650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (std::set<RegiT>::const_iterator iter = loopLand->contOnRegs.begin(), 1651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org iterEnd = loopLand->contOnRegs.end(); iter != iterEnd; ++iter) { 1652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org CFGTraits::insertCondBranchEnd(dstBlk, AMDGPU::CONTINUE_LOGICALNZ_i32, 1653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org passRep, *iter); 1654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dstBlk->splice(dstBlk->end(), landBlk, landBlk->begin(), landBlk->end()); 1657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (typename BlockT::succ_iterator iter = landBlk->succ_begin(), 1659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org iterEnd = landBlk->succ_end(); iter != iterEnd; ++iter) { 1660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dstBlk->addSuccessor(*iter); // *iter's predecessor is also taken care of. 1661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org removeSuccessor(landBlk); 1664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org retireBlock(dstBlk, landBlk); 1665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //mergeLooplandBlock 1666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT> 1668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid CFGStructurizer<PassT>::reversePredicateSetter(typename BlockT::iterator I) 1669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org while (I--) { 1671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (I->getOpcode() == AMDGPU::PRED_X) { 1672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch (static_cast<MachineInstr *>(I)->getOperand(2).getImm()) { 1673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_IS_ZERO_INT: 1674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static_cast<MachineInstr *>(I)->getOperand(2).setImm(OPCODE_IS_NOT_ZERO_INT); 1675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 1676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_IS_NOT_ZERO_INT: 1677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static_cast<MachineInstr *>(I)->getOperand(2).setImm(OPCODE_IS_ZERO_INT); 1678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 1679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_IS_ZERO: 1680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static_cast<MachineInstr *>(I)->getOperand(2).setImm(OPCODE_IS_NOT_ZERO); 1681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 1682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case OPCODE_IS_NOT_ZERO: 1683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static_cast<MachineInstr *>(I)->getOperand(2).setImm(OPCODE_IS_ZERO); 1684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 1685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 1686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(0 && "PRED_X Opcode invalid!"); 1687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT> 1693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid CFGStructurizer<PassT>::mergeLoopbreakBlock(BlockT *exitingBlk, 1694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *exitBlk, 1695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *exitLandBlk, 1696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RegiT setReg) { 1697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUGME) { 1698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "loopbreakPattern exiting = BB" << exitingBlk->getNumber() 1699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org << " exit = BB" << exitBlk->getNumber() 1700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org << " land = BB" << exitLandBlk->getNumber() << "\n"; 1701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org InstrT *branchInstr = CFGTraits::getLoopendBlockBranchInstr(exitingBlk); 1704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(branchInstr && CFGTraits::isCondBranch(branchInstr)); 1705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org DebugLoc DL = branchInstr->getDebugLoc(); 1707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *trueBranch = CFGTraits::getTrueBranch(branchInstr); 1709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int oldOpcode = branchInstr->getOpcode(); 1710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // transform exitingBlk to 1712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // if ( ) { 1713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // exitBlk (if exitBlk != exitLandBlk) 1714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // setReg = 1 1715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // break 1716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // }endif 1717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // successor = {orgSuccessor(exitingBlk) - exitBlk} 1718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org typename BlockT::iterator branchInstrPos = 1720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org CFGTraits::getInstrPos(exitingBlk, branchInstr); 1721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (exitBlk == exitLandBlk && setReg == INVALIDREGNUM) { 1723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //break_logical 1724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (trueBranch != exitBlk) { 1726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org reversePredicateSetter(branchInstrPos); 1727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int newOpcode = CFGTraits::getBreakZeroOpcode(oldOpcode); 1729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org CFGTraits::insertCondBranchBefore(branchInstrPos, newOpcode, passRep, DL); 1730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 1731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (trueBranch != exitBlk) { 1732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org reversePredicateSetter(branchInstr); 1733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int newOpcode = CFGTraits::getBreakZeroOpcode(oldOpcode); 1735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org CFGTraits::insertCondBranchBefore(branchInstrPos, newOpcode, passRep, DL); 1736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (exitBlk != exitLandBlk) { 1737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //splice is insert-before ... 1738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org exitingBlk->splice(branchInstrPos, exitBlk, exitBlk->begin(), 1739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org exitBlk->end()); 1740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (setReg != INVALIDREGNUM) { 1742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org CFGTraits::insertAssignInstrBefore(branchInstrPos, passRep, setReg, 1); 1743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org CFGTraits::insertInstrBefore(branchInstrPos, AMDGPU::BREAK, passRep); 1745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org CFGTraits::insertInstrBefore(branchInstrPos, AMDGPU::ENDIF, passRep); 1746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } //if_logical 1747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //now branchInst can be erase safely 1749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //exitingBlk->eraseFromParent(branchInstr); 1750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org branchInstr->eraseFromParent(); 1751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //now take care of successors, retire blocks 1753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org exitingBlk->removeSuccessor(exitBlk); 1754f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (exitBlk != exitLandBlk) { 1755f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //splice is insert-before ... 1756f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org exitBlk->removeSuccessor(exitLandBlk); 1757f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org retireBlock(exitingBlk, exitBlk); 1758f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1759f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1760f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //mergeLoopbreakBlock 1761f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1762f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT> 1763f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid CFGStructurizer<PassT>::settleLoopcontBlock(BlockT *contingBlk, 1764f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *contBlk, 1765f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RegiT setReg) { 1766f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUGME) { 1767f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "settleLoopcontBlock conting = BB" 1768f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org << contingBlk->getNumber() 1769f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org << ", cont = BB" << contBlk->getNumber() << "\n"; 1770f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1771f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1772f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org InstrT *branchInstr = CFGTraits::getLoopendBlockBranchInstr(contingBlk); 1773f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (branchInstr) { 1774f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(CFGTraits::isCondBranch(branchInstr)); 1775f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org typename BlockT::iterator branchInstrPos = 1776f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org CFGTraits::getInstrPos(contingBlk, branchInstr); 1777f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *trueBranch = CFGTraits::getTrueBranch(branchInstr); 1778f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int oldOpcode = branchInstr->getOpcode(); 1779f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org DebugLoc DL = branchInstr->getDebugLoc(); 1780f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1781f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // transform contingBlk to 1782f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // if () { 1783f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // move instr after branchInstr 1784f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // continue 1785f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // or 1786f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // setReg = 1 1787f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // break 1788f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // }endif 1789f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // successor = {orgSuccessor(contingBlk) - loopHeader} 1790f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1791f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool useContinueLogical = 1792f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (setReg == INVALIDREGNUM && (&*contingBlk->rbegin()) == branchInstr); 1793f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1794f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (useContinueLogical == false) 1795f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1796f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int branchOpcode = 1797f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org trueBranch == contBlk ? CFGTraits::getBranchNzeroOpcode(oldOpcode) 1798f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org : CFGTraits::getBranchZeroOpcode(oldOpcode); 1799f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1800f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org CFGTraits::insertCondBranchBefore(branchInstrPos, branchOpcode, passRep, DL); 1801f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1802f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (setReg != INVALIDREGNUM) { 1803f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org CFGTraits::insertAssignInstrBefore(branchInstrPos, passRep, setReg, 1); 1804f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // insertEnd to ensure phi-moves, if exist, go before the continue-instr. 1805f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org CFGTraits::insertInstrEnd(contingBlk, AMDGPU::BREAK, passRep, DL); 1806f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 1807f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // insertEnd to ensure phi-moves, if exist, go before the continue-instr. 1808f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org CFGTraits::insertInstrEnd(contingBlk, AMDGPU::CONTINUE, passRep, DL); 1809f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1810f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1811f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org CFGTraits::insertInstrEnd(contingBlk, AMDGPU::ENDIF, passRep, DL); 1812f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 1813f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int branchOpcode = 1814f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org trueBranch == contBlk ? CFGTraits::getContinueNzeroOpcode(oldOpcode) 1815f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org : CFGTraits::getContinueZeroOpcode(oldOpcode); 1816f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1817f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org CFGTraits::insertCondBranchBefore(branchInstrPos, branchOpcode, passRep, DL); 1818f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1819f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1820f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //contingBlk->eraseFromParent(branchInstr); 1821f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org branchInstr->eraseFromParent(); 1822f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 1823f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* if we've arrived here then we've already erased the branch instruction 1824f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * travel back up the basic block to see the last reference of our debug location 1825f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * we've just inserted that reference here so it should be representative */ 1826f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (setReg != INVALIDREGNUM) { 1827f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org CFGTraits::insertAssignInstrBefore(contingBlk, passRep, setReg, 1); 1828f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // insertEnd to ensure phi-moves, if exist, go before the continue-instr. 1829f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org CFGTraits::insertInstrEnd(contingBlk, AMDGPU::BREAK, passRep, CFGTraits::getLastDebugLocInBB(contingBlk)); 1830f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 1831f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // insertEnd to ensure phi-moves, if exist, go before the continue-instr. 1832f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org CFGTraits::insertInstrEnd(contingBlk, AMDGPU::CONTINUE, passRep, CFGTraits::getLastDebugLocInBB(contingBlk)); 1833f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1834f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } //else 1835f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1836f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //settleLoopcontBlock 1837f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1838f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// BBs in exitBlkSet are determined as in break-path for loopRep, 1839f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// before we can put code for BBs as inside loop-body for loopRep 1840f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// check whether those BBs are determined as cont-BB for parentLoopRep 1841f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// earlier. 1842f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// If so, generate a new BB newBlk 1843f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// (1) set newBlk common successor of BBs in exitBlkSet 1844f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// (2) change the continue-instr in BBs in exitBlkSet to break-instr 1845f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// (3) generate continue-instr in newBlk 1846f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// 1847f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT> 1848f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtypename CFGStructurizer<PassT>::BlockT * 1849f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgCFGStructurizer<PassT>::relocateLoopcontBlock(LoopT *parentLoopRep, 1850f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LoopT *loopRep, 1851f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org std::set<BlockT *> &exitBlkSet, 1852f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *exitLandBlk) { 1853f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org std::set<BlockT *> endBlkSet; 1854f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1855f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// BlockT *parentLoopHead = parentLoopRep->getHeader(); 1856f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1857f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1858f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (typename std::set<BlockT *>::const_iterator iter = exitBlkSet.begin(), 1859f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org iterEnd = exitBlkSet.end(); 1860f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org iter != iterEnd; ++iter) { 1861f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *exitBlk = *iter; 1862f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *endBlk = singlePathEnd(exitBlk, exitLandBlk); 1863f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1864f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (endBlk == NULL || CFGTraits::getContinueInstr(endBlk) == NULL) 1865f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 1866f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1867f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org endBlkSet.insert(endBlk); 1868f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1869f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1870f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *newBlk = funcRep->CreateMachineBasicBlock(); 1871f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org funcRep->push_back(newBlk); //insert to function 1872f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org CFGTraits::insertInstrEnd(newBlk, AMDGPU::CONTINUE, passRep); 1873f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SHOWNEWBLK(newBlk, "New continue block: "); 1874f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1875f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (typename std::set<BlockT*>::const_iterator iter = endBlkSet.begin(), 1876f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org iterEnd = endBlkSet.end(); 1877f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org iter != iterEnd; ++iter) { 1878f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *endBlk = *iter; 1879f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org InstrT *contInstr = CFGTraits::getContinueInstr(endBlk); 1880f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (contInstr) { 1881f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org contInstr->eraseFromParent(); 1882f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1883f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org endBlk->addSuccessor(newBlk); 1884f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUGME) { 1885f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "Add new continue Block to BB" 1886f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org << endBlk->getNumber() << " successors\n"; 1887f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1888f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1889f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1890f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return newBlk; 1891f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //relocateLoopcontBlock 1892f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1893f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1894f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// LoopEndbranchBlock is a BB created by the CFGStructurizer to use as 1895f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// LoopLandBlock. This BB branch on the loop endBranchInit register to the 1896f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// pathes corresponding to the loop exiting branches. 1897f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1898f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT> 1899f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtypename CFGStructurizer<PassT>::BlockT * 1900f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgCFGStructurizer<PassT>::addLoopEndbranchBlock(LoopT *loopRep, 1901f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockTSmallerVector &exitingBlks, 1902f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockTSmallerVector &exitBlks) { 1903f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const AMDGPUInstrInfo *tii = 1904f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static_cast<const AMDGPUInstrInfo *>(passRep->getTargetInstrInfo()); 1905f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const TargetRegisterClass * I32RC = TRI->getCFGStructurizerRegClass(MVT::i32); 1906f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1907f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RegiT endBranchReg = static_cast<int> 1908f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (funcRep->getRegInfo().createVirtualRegister(I32RC)); 1909f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(endBranchReg >= 0); 1910f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1911f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // reg = 0 before entering the loop 1912f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org addLoopEndbranchInitReg(loopRep, endBranchReg); 1913f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1914f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org uint32_t numBlks = static_cast<uint32_t>(exitingBlks.size()); 1915f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(numBlks >=2 && numBlks == exitBlks.size()); 1916f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1917f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *preExitingBlk = exitingBlks[0]; 1918f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *preExitBlk = exitBlks[0]; 1919f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *preBranchBlk = funcRep->CreateMachineBasicBlock(); 1920f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org funcRep->push_back(preBranchBlk); //insert to function 1921f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SHOWNEWBLK(preBranchBlk, "New loopEndbranch block: "); 1922f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1923f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *newLandBlk = preBranchBlk; 1924f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1925f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org CFGTraits::replaceInstrUseOfBlockWith(preExitingBlk, preExitBlk, 1926f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org newLandBlk); 1927f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org preExitingBlk->removeSuccessor(preExitBlk); 1928f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org preExitingBlk->addSuccessor(newLandBlk); 1929f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1930f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //it is redundant to add reg = 0 to exitingBlks[0] 1931f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1932f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // For 1..n th exiting path (the last iteration handles two pathes) create the 1933f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // branch to the previous path and the current path. 1934f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (uint32_t i = 1; i < numBlks; ++i) { 1935f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *curExitingBlk = exitingBlks[i]; 1936f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *curExitBlk = exitBlks[i]; 1937f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *curBranchBlk; 1938f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1939f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (i == numBlks - 1) { 1940f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org curBranchBlk = curExitBlk; 1941f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 1942f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org curBranchBlk = funcRep->CreateMachineBasicBlock(); 1943f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org funcRep->push_back(curBranchBlk); //insert to function 1944f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SHOWNEWBLK(curBranchBlk, "New loopEndbranch block: "); 1945f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1946f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1947f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // Add reg = i to exitingBlks[i]. 1948f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org CFGTraits::insertAssignInstrBefore(curExitingBlk, passRep, 1949f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org endBranchReg, i); 1950f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1951f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // Remove the edge (exitingBlks[i] exitBlks[i]) add new edge 1952f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // (exitingBlks[i], newLandBlk). 1953f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org CFGTraits::replaceInstrUseOfBlockWith(curExitingBlk, curExitBlk, 1954f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org newLandBlk); 1955f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org curExitingBlk->removeSuccessor(curExitBlk); 1956f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org curExitingBlk->addSuccessor(newLandBlk); 1957f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1958f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // add to preBranchBlk the branch instruction: 1959f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // if (endBranchReg == preVal) 1960f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // preExitBlk 1961f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // else 1962f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // curBranchBlk 1963f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // 1964f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // preValReg = i - 1 1965f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1966f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org DebugLoc DL; 1967f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RegiT preValReg = static_cast<int> 1968f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (funcRep->getRegInfo().createVirtualRegister(I32RC)); 1969f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1970f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org preBranchBlk->insert(preBranchBlk->begin(), 1971f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tii->getMovImmInstr(preBranchBlk->getParent(), preValReg, 1972f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org i - 1)); 1973f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1974f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // condResReg = (endBranchReg == preValReg) 1975f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RegiT condResReg = static_cast<int> 1976f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (funcRep->getRegInfo().createVirtualRegister(I32RC)); 1977f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BuildMI(preBranchBlk, DL, tii->get(tii->getIEQOpcode()), condResReg) 1978f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org .addReg(endBranchReg).addReg(preValReg); 1979f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1980f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BuildMI(preBranchBlk, DL, tii->get(AMDGPU::BRANCH_COND_i32)) 1981f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org .addMBB(preExitBlk).addReg(condResReg); 1982f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1983f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org preBranchBlk->addSuccessor(preExitBlk); 1984f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org preBranchBlk->addSuccessor(curBranchBlk); 1985f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1986f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // Update preExitingBlk, preExitBlk, preBranchBlk. 1987f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org preExitingBlk = curExitingBlk; 1988f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org preExitBlk = curExitBlk; 1989f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org preBranchBlk = curBranchBlk; 1990f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1991f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } //end for 1 .. n blocks 1992f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1993f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return newLandBlk; 1994f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //addLoopEndbranchBlock 1995f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1996f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT> 1997f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtypename CFGStructurizer<PassT>::PathToKind 1998f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgCFGStructurizer<PassT>::singlePathTo(BlockT *srcBlk, BlockT *dstBlk, 1999f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool allowSideEntry) { 2000f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(dstBlk); 2001f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2002f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (srcBlk == dstBlk) { 2003f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return SinglePath_InPath; 2004f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2005f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2006f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org while (srcBlk && srcBlk->succ_size() == 1) { 2007f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org srcBlk = *srcBlk->succ_begin(); 2008f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (srcBlk == dstBlk) { 2009f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return SinglePath_InPath; 2010f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2011f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2012f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!allowSideEntry && srcBlk->pred_size() > 1) { 2013f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return Not_SinglePath; 2014f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2015f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2016f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2017f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (srcBlk && srcBlk->succ_size()==0) { 2018f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return SinglePath_NotInPath; 2019f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2020f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2021f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return Not_SinglePath; 2022f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //singlePathTo 2023f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2024f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// If there is a single path from srcBlk to dstBlk, return the last block before 2025f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// dstBlk If there is a single path from srcBlk->end without dstBlk, return the 2026f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// last block in the path Otherwise, return NULL 2027f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT> 2028f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtypename CFGStructurizer<PassT>::BlockT * 2029f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgCFGStructurizer<PassT>::singlePathEnd(BlockT *srcBlk, BlockT *dstBlk, 2030f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool allowSideEntry) { 2031f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(dstBlk); 2032f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2033f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (srcBlk == dstBlk) { 2034f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return srcBlk; 2035f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2036f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2037f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (srcBlk->succ_size() == 0) { 2038f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return srcBlk; 2039f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2040f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2041f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org while (srcBlk && srcBlk->succ_size() == 1) { 2042f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *preBlk = srcBlk; 2043f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2044f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org srcBlk = *srcBlk->succ_begin(); 2045f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (srcBlk == NULL) { 2046f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return preBlk; 2047f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2048f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2049f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!allowSideEntry && srcBlk->pred_size() > 1) { 2050f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 2051f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2052f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2053f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2054f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (srcBlk && srcBlk->succ_size()==0) { 2055f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return srcBlk; 2056f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2057f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2058f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 2059f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2060f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //singlePathEnd 2061f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2062f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT> 2063f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgint CFGStructurizer<PassT>::cloneOnSideEntryTo(BlockT *preBlk, BlockT *srcBlk, 2064f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *dstBlk) { 2065f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int cloned = 0; 2066f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(preBlk->isSuccessor(srcBlk)); 2067f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org while (srcBlk && srcBlk != dstBlk) { 2068f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(srcBlk->succ_size() == 1); 2069f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (srcBlk->pred_size() > 1) { 2070f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org srcBlk = cloneBlockForPredecessor(srcBlk, preBlk); 2071f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ++cloned; 2072f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2073f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2074f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org preBlk = srcBlk; 2075f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org srcBlk = *srcBlk->succ_begin(); 2076f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2077f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2078f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return cloned; 2079f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //cloneOnSideEntryTo 2080f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2081f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT> 2082f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtypename CFGStructurizer<PassT>::BlockT * 2083f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgCFGStructurizer<PassT>::cloneBlockForPredecessor(BlockT *curBlk, 2084f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *predBlk) { 2085f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(predBlk->isSuccessor(curBlk) && 2086f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "succBlk is not a prececessor of curBlk"); 2087f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2088f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *cloneBlk = CFGTraits::clone(curBlk); //clone instructions 2089f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org CFGTraits::replaceInstrUseOfBlockWith(predBlk, curBlk, cloneBlk); 2090f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //srcBlk, oldBlk, newBlk 2091f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2092f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org predBlk->removeSuccessor(curBlk); 2093f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org predBlk->addSuccessor(cloneBlk); 2094f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2095f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // add all successor to cloneBlk 2096f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org CFGTraits::cloneSuccessorList(cloneBlk, curBlk); 2097f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2098f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org numClonedInstr += curBlk->size(); 2099f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUGME) { 2101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "Cloned block: " << "BB" 2102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org << curBlk->getNumber() << "size " << curBlk->size() << "\n"; 2103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SHOWNEWBLK(cloneBlk, "result of Cloned block: "); 2106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return cloneBlk; 2108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //cloneBlockForPredecessor 2109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT> 2111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtypename CFGStructurizer<PassT>::BlockT * 2112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgCFGStructurizer<PassT>::exitingBlock2ExitBlock(LoopT *loopRep, 2113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *exitingBlk) { 2114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *exitBlk = NULL; 2115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (typename BlockT::succ_iterator iterSucc = exitingBlk->succ_begin(), 2117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org iterSuccEnd = exitingBlk->succ_end(); 2118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org iterSucc != iterSuccEnd; ++iterSucc) { 2119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *curBlk = *iterSucc; 2120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!loopRep->contains(curBlk)) { 2121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(exitBlk == NULL); 2122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org exitBlk = curBlk; 2123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(exitBlk != NULL); 2127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return exitBlk; 2129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //exitingBlock2ExitBlock 2130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT> 2132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid CFGStructurizer<PassT>::migrateInstruction(BlockT *srcBlk, 2133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *dstBlk, 2134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org InstrIterator insertPos) { 2135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org InstrIterator spliceEnd; 2136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //look for the input branchinstr, not the AMDGPU branchinstr 2137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org InstrT *branchInstr = CFGTraits::getNormalBlockBranchInstr(srcBlk); 2138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (branchInstr == NULL) { 2139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUGME) { 2140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "migrateInstruction don't see branch instr\n" ; 2141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org spliceEnd = srcBlk->end(); 2143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 2144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUGME) { 2145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "migrateInstruction see branch instr\n" ; 2146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org branchInstr->dump(); 2147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org spliceEnd = CFGTraits::getInstrPos(srcBlk, branchInstr); 2149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUGME) { 2151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "migrateInstruction before splice dstSize = " << dstBlk->size() 2152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org << "srcSize = " << srcBlk->size() << "\n"; 2153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //splice insert before insertPos 2156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dstBlk->splice(insertPos, srcBlk, srcBlk->begin(), spliceEnd); 2157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUGME) { 2159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "migrateInstruction after splice dstSize = " << dstBlk->size() 2160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org << "srcSize = " << srcBlk->size() << "\n"; 2161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //migrateInstruction 2163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// normalizeInfiniteLoopExit change 2165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// B1: 2166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// uncond_br LoopHeader 2167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// 2168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// to 2169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// B1: 2170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// cond_br 1 LoopHeader dummyExit 2171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// and return the newly added dummy exit block 2172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// 2173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT> 2174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtypename CFGStructurizer<PassT>::BlockT * 2175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgCFGStructurizer<PassT>::normalizeInfiniteLoopExit(LoopT* LoopRep) { 2176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *loopHeader; 2177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *loopLatch; 2178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org loopHeader = LoopRep->getHeader(); 2179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org loopLatch = LoopRep->getLoopLatch(); 2180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *dummyExitBlk = NULL; 2181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const TargetRegisterClass * I32RC = TRI->getCFGStructurizerRegClass(MVT::i32); 2182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (loopHeader!=NULL && loopLatch!=NULL) { 2183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org InstrT *branchInstr = CFGTraits::getLoopendBlockBranchInstr(loopLatch); 2184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (branchInstr!=NULL && CFGTraits::isUncondBranch(branchInstr)) { 2185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dummyExitBlk = funcRep->CreateMachineBasicBlock(); 2186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org funcRep->push_back(dummyExitBlk); //insert to function 2187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SHOWNEWBLK(dummyExitBlk, "DummyExitBlock to normalize infiniteLoop: "); 2188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUGME) errs() << "Old branch instr: " << *branchInstr << "\n"; 2190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org typename BlockT::iterator insertPos = 2192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org CFGTraits::getInstrPos(loopLatch, branchInstr); 2193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned immReg = 2194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org funcRep->getRegInfo().createVirtualRegister(I32RC); 2195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org CFGTraits::insertAssignInstrBefore(insertPos, passRep, immReg, 1); 2196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org InstrT *newInstr = 2197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org CFGTraits::insertInstrBefore(insertPos, AMDGPU::BRANCH_COND_i32, passRep); 2198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org MachineInstrBuilder(newInstr).addMBB(loopHeader).addReg(immReg, false); 2199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SHOWNEWINSTR(newInstr); 2201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org branchInstr->eraseFromParent(); 2203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org loopLatch->addSuccessor(dummyExitBlk); 2204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return dummyExitBlk; 2208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //normalizeInfiniteLoopExit 2209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT> 2211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid CFGStructurizer<PassT>::removeUnconditionalBranch(BlockT *srcBlk) { 2212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org InstrT *branchInstr; 2213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // I saw two unconditional branch in one basic block in example 2215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // test_fc_do_while_or.c need to fix the upstream on this to remove the loop. 2216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org while ((branchInstr = CFGTraits::getLoopendBlockBranchInstr(srcBlk)) 2217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && CFGTraits::isUncondBranch(branchInstr)) { 2218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUGME) { 2219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "Removing unconditional branch instruction" ; 2220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org branchInstr->dump(); 2221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org branchInstr->eraseFromParent(); 2223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //removeUnconditionalBranch 2225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT> 2227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid CFGStructurizer<PassT>::removeRedundantConditionalBranch(BlockT *srcBlk) { 2228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (srcBlk->succ_size() == 2) { 2229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *blk1 = *srcBlk->succ_begin(); 2230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *blk2 = *(++srcBlk->succ_begin()); 2231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (blk1 == blk2) { 2233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org InstrT *branchInstr = CFGTraits::getNormalBlockBranchInstr(srcBlk); 2234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(branchInstr && CFGTraits::isCondBranch(branchInstr)); 2235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUGME) { 2236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "Removing unneeded conditional branch instruction" ; 2237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org branchInstr->dump(); 2238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org branchInstr->eraseFromParent(); 2240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SHOWNEWBLK(blk1, "Removing redundant successor"); 2241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org srcBlk->removeSuccessor(blk1); 2242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //removeRedundantConditionalBranch 2245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT> 2247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid CFGStructurizer<PassT>::addDummyExitBlock(SmallVector<BlockT*, 2248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org DEFAULT_VEC_SLOTS> &retBlks) { 2249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *dummyExitBlk = funcRep->CreateMachineBasicBlock(); 2250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org funcRep->push_back(dummyExitBlk); //insert to function 2251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org CFGTraits::insertInstrEnd(dummyExitBlk, AMDGPU::RETURN, passRep); 2252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (typename SmallVector<BlockT *, DEFAULT_VEC_SLOTS>::iterator iter = 2254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org retBlks.begin(), 2255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org iterEnd = retBlks.end(); iter != iterEnd; ++iter) { 2256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *curBlk = *iter; 2257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org InstrT *curInstr = CFGTraits::getReturnInstr(curBlk); 2258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (curInstr) { 2259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org curInstr->eraseFromParent(); 2260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if 0 2262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (curBlk->size()==0 && curBlk->pred_size() == 1) { 2263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUGME) { 2264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "Replace empty block BB" << curBlk->getNumber() 2265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org << " with dummyExitBlock\n"; 2266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *predb = *curBlk->pred_begin(); 2268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org predb->removeSuccessor(curBlk); 2269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org curBlk = predb; 2270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } //handle empty curBlk 2271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 2272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org curBlk->addSuccessor(dummyExitBlk); 2273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUGME) { 2274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "Add dummyExitBlock to BB" << curBlk->getNumber() 2275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org << " successors\n"; 2276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } //for 2278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SHOWNEWBLK(dummyExitBlk, "DummyExitBlock: "); 2280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //addDummyExitBlock 2281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT> 2283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid CFGStructurizer<PassT>::removeSuccessor(BlockT *srcBlk) { 2284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org while (srcBlk->succ_size()) { 2285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org srcBlk->removeSuccessor(*srcBlk->succ_begin()); 2286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 2288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT> 2290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid CFGStructurizer<PassT>::recordSccnum(BlockT *srcBlk, int sccNum) { 2291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockInfo *&srcBlkInfo = blockInfoMap[srcBlk]; 2292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (srcBlkInfo == NULL) { 2294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org srcBlkInfo = new BlockInfo(); 2295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org srcBlkInfo->sccNum = sccNum; 2298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 2299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT> 2301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgint CFGStructurizer<PassT>::getSCCNum(BlockT *srcBlk) { 2302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockInfo *srcBlkInfo = blockInfoMap[srcBlk]; 2303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return srcBlkInfo ? srcBlkInfo->sccNum : INVALIDSCCNUM; 2304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 2305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT> 2307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid CFGStructurizer<PassT>::retireBlock(BlockT *dstBlk, BlockT *srcBlk) { 2308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUGME) { 2309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "Retiring BB" << srcBlk->getNumber() << "\n"; 2310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockInfo *&srcBlkInfo = blockInfoMap[srcBlk]; 2313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (srcBlkInfo == NULL) { 2315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org srcBlkInfo = new BlockInfo(); 2316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org srcBlkInfo->isRetired = true; 2319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //int i = srcBlk->succ_size(); 2320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //int j = srcBlk->pred_size(); 2321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(srcBlk->succ_size() == 0 && srcBlk->pred_size() == 0 2322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && "can't retire block yet"); 2323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 2324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT> 2326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool CFGStructurizer<PassT>::isRetiredBlock(BlockT *srcBlk) { 2327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockInfo *srcBlkInfo = blockInfoMap[srcBlk]; 2328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return (srcBlkInfo && srcBlkInfo->isRetired); 2329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 2330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT> 2332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool CFGStructurizer<PassT>::isActiveLoophead(BlockT *curBlk) { 2333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LoopT *loopRep = loopInfo->getLoopFor(curBlk); 2334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org while (loopRep && loopRep->getHeader() == curBlk) { 2335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LoopLandInfo *loopLand = getLoopLandInfo(loopRep); 2336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(loopLand == NULL) 2338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return true; 2339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *landBlk = loopLand->landBlk; 2341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(landBlk); 2342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!isRetiredBlock(landBlk)) { 2343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return true; 2344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org loopRep = loopRep->getParentLoop(); 2347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return false; 2350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //isActiveLoophead 2351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT> 2353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool CFGStructurizer<PassT>::needMigrateBlock(BlockT *blk) { 2354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const unsigned blockSizeThreshold = 30; 2355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const unsigned cloneInstrThreshold = 100; 2356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool multiplePreds = blk && (blk->pred_size() > 1); 2358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(!multiplePreds) 2360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return false; 2361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned blkSize = blk->size(); 2363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return ((blkSize > blockSizeThreshold) 2364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && (blkSize * (blk->pred_size() - 1) > cloneInstrThreshold)); 2365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //needMigrateBlock 2366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT> 2368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtypename CFGStructurizer<PassT>::BlockT * 2369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgCFGStructurizer<PassT>::recordLoopLandBlock(LoopT *loopRep, BlockT *landBlk, 2370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockTSmallerVector &exitBlks, 2371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org std::set<BlockT *> &exitBlkSet) { 2372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SmallVector<BlockT *, DEFAULT_VEC_SLOTS> inpathBlks; //in exit path blocks 2373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (typename BlockT::pred_iterator predIter = landBlk->pred_begin(), 2375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org predIterEnd = landBlk->pred_end(); 2376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org predIter != predIterEnd; ++predIter) { 2377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *curBlk = *predIter; 2378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (loopRep->contains(curBlk) || exitBlkSet.count(curBlk)) { 2379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inpathBlks.push_back(curBlk); 2380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } //for 2382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //if landBlk has predecessors that are not in the given loop, 2384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //create a new block 2385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *newLandBlk = landBlk; 2386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inpathBlks.size() != landBlk->pred_size()) { 2387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org newLandBlk = funcRep->CreateMachineBasicBlock(); 2388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org funcRep->push_back(newLandBlk); //insert to function 2389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org newLandBlk->addSuccessor(landBlk); 2390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (typename SmallVector<BlockT*, DEFAULT_VEC_SLOTS>::iterator iter = 2391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inpathBlks.begin(), 2392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org iterEnd = inpathBlks.end(); iter != iterEnd; ++iter) { 2393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *curBlk = *iter; 2394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org CFGTraits::replaceInstrUseOfBlockWith(curBlk, landBlk, newLandBlk); 2395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //srcBlk, oldBlk, newBlk 2396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org curBlk->removeSuccessor(landBlk); 2397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org curBlk->addSuccessor(newLandBlk); 2398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (size_t i = 0, tot = exitBlks.size(); i < tot; ++i) { 2400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (exitBlks[i] == landBlk) { 2401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org exitBlks[i] = newLandBlk; 2402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SHOWNEWBLK(newLandBlk, "NewLandingBlock: "); 2405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org setLoopLandBlock(loopRep, newLandBlk); 2408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return newLandBlk; 2410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} // recordLoopbreakLand 2411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT> 2413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid CFGStructurizer<PassT>::setLoopLandBlock(LoopT *loopRep, BlockT *blk) { 2414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LoopLandInfo *&theEntry = loopLandInfoMap[loopRep]; 2415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (theEntry == NULL) { 2417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org theEntry = new LoopLandInfo(); 2418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(theEntry->landBlk == NULL); 2420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (blk == NULL) { 2422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org blk = funcRep->CreateMachineBasicBlock(); 2423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org funcRep->push_back(blk); //insert to function 2424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SHOWNEWBLK(blk, "DummyLandingBlock for loop without break: "); 2425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org theEntry->landBlk = blk; 2428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUGME) { 2430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "setLoopLandBlock loop-header = BB" 2431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org << loopRep->getHeader()->getNumber() 2432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org << " landing-block = BB" << blk->getNumber() << "\n"; 2433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} // setLoopLandBlock 2435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT> 2437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid CFGStructurizer<PassT>::addLoopBreakOnReg(LoopT *loopRep, RegiT regNum) { 2438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LoopLandInfo *&theEntry = loopLandInfoMap[loopRep]; 2439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (theEntry == NULL) { 2441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org theEntry = new LoopLandInfo(); 2442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org theEntry->breakOnRegs.insert(regNum); 2445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUGME) { 2447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "addLoopBreakOnReg loop-header = BB" 2448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org << loopRep->getHeader()->getNumber() 2449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org << " regNum = " << regNum << "\n"; 2450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} // addLoopBreakOnReg 2452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT> 2454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid CFGStructurizer<PassT>::addLoopContOnReg(LoopT *loopRep, RegiT regNum) { 2455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LoopLandInfo *&theEntry = loopLandInfoMap[loopRep]; 2456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (theEntry == NULL) { 2458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org theEntry = new LoopLandInfo(); 2459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org theEntry->contOnRegs.insert(regNum); 2461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUGME) { 2463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "addLoopContOnReg loop-header = BB" 2464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org << loopRep->getHeader()->getNumber() 2465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org << " regNum = " << regNum << "\n"; 2466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} // addLoopContOnReg 2468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT> 2470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid CFGStructurizer<PassT>::addLoopBreakInitReg(LoopT *loopRep, RegiT regNum) { 2471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LoopLandInfo *&theEntry = loopLandInfoMap[loopRep]; 2472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (theEntry == NULL) { 2474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org theEntry = new LoopLandInfo(); 2475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org theEntry->breakInitRegs.insert(regNum); 2477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUGME) { 2479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "addLoopBreakInitReg loop-header = BB" 2480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org << loopRep->getHeader()->getNumber() 2481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org << " regNum = " << regNum << "\n"; 2482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} // addLoopBreakInitReg 2484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT> 2486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid CFGStructurizer<PassT>::addLoopContInitReg(LoopT *loopRep, RegiT regNum) { 2487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LoopLandInfo *&theEntry = loopLandInfoMap[loopRep]; 2488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (theEntry == NULL) { 2490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org theEntry = new LoopLandInfo(); 2491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org theEntry->contInitRegs.insert(regNum); 2493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUGME) { 2495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "addLoopContInitReg loop-header = BB" 2496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org << loopRep->getHeader()->getNumber() 2497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org << " regNum = " << regNum << "\n"; 2498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} // addLoopContInitReg 2500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT> 2502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid CFGStructurizer<PassT>::addLoopEndbranchInitReg(LoopT *loopRep, 2503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RegiT regNum) { 2504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LoopLandInfo *&theEntry = loopLandInfoMap[loopRep]; 2505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (theEntry == NULL) { 2507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org theEntry = new LoopLandInfo(); 2508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org theEntry->endbranchInitRegs.insert(regNum); 2510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUGME) 2512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 2513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "addLoopEndbranchInitReg loop-header = BB" 2514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org << loopRep->getHeader()->getNumber() 2515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org << " regNum = " << regNum << "\n"; 2516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} // addLoopEndbranchInitReg 2518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT> 2520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtypename CFGStructurizer<PassT>::LoopLandInfo * 2521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgCFGStructurizer<PassT>::getLoopLandInfo(LoopT *loopRep) { 2522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LoopLandInfo *&theEntry = loopLandInfoMap[loopRep]; 2523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return theEntry; 2525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} // getLoopLandInfo 2526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT> 2528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtypename CFGStructurizer<PassT>::BlockT * 2529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgCFGStructurizer<PassT>::getLoopLandBlock(LoopT *loopRep) { 2530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LoopLandInfo *&theEntry = loopLandInfoMap[loopRep]; 2531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return theEntry ? theEntry->landBlk : NULL; 2533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} // getLoopLandBlock 2534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT> 2537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool CFGStructurizer<PassT>::hasBackEdge(BlockT *curBlk) { 2538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LoopT *loopRep = loopInfo->getLoopFor(curBlk); 2539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (loopRep == NULL) 2540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return false; 2541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *loopHeader = loopRep->getHeader(); 2543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return curBlk->isSuccessor(loopHeader); 2545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //hasBackEdge 2547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT> 2549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgunsigned CFGStructurizer<PassT>::getLoopDepth(LoopT *loopRep) { 2550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return loopRep ? loopRep->getLoopDepth() : 0; 2551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //getLoopDepth 2552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT> 2554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgint CFGStructurizer<PassT>::countActiveBlock 2555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org(typename SmallVector<BlockT*, DEFAULT_VEC_SLOTS>::const_iterator iterStart, 2556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org typename SmallVector<BlockT*, DEFAULT_VEC_SLOTS>::const_iterator iterEnd) { 2557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int count = 0; 2558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org while (iterStart != iterEnd) { 2559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!isRetiredBlock(*iterStart)) { 2560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ++count; 2561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ++iterStart; 2563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return count; 2566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //countActiveBlock 2567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// This is work around solution for findNearestCommonDominator not avaiable to 2569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// post dom a proper fix should go to Dominators.h. 2570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT> 2572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtypename CFGStructurizer<PassT>::BlockT* 2573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgCFGStructurizer<PassT>::findNearestCommonPostDom(BlockT *blk1, BlockT *blk2) { 2574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (postDomTree->dominates(blk1, blk2)) { 2576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return blk1; 2577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (postDomTree->dominates(blk2, blk1)) { 2579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return blk2; 2580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org DomTreeNodeT *node1 = postDomTree->getNode(blk1); 2583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org DomTreeNodeT *node2 = postDomTree->getNode(blk2); 2584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // Handle newly cloned node. 2586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (node1 == NULL && blk1->succ_size() == 1) { 2587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return findNearestCommonPostDom(*blk1->succ_begin(), blk2); 2588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (node2 == NULL && blk2->succ_size() == 1) { 2590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return findNearestCommonPostDom(blk1, *blk2->succ_begin()); 2591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (node1 == NULL || node2 == NULL) { 2594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 2595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org node1 = node1->getIDom(); 2598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org while (node1) { 2599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (postDomTree->dominates(node1, node2)) { 2600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return node1->getBlock(); 2601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org node1 = node1->getIDom(); 2603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 2606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 2607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT> 2609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtypename CFGStructurizer<PassT>::BlockT * 2610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgCFGStructurizer<PassT>::findNearestCommonPostDom 2611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org(typename std::set<BlockT *> &blks) { 2612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *commonDom; 2613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org typename std::set<BlockT *>::const_iterator iter = blks.begin(); 2614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org typename std::set<BlockT *>::const_iterator iterEnd = blks.end(); 2615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (commonDom = *iter; iter != iterEnd && commonDom != NULL; ++iter) { 2616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BlockT *curBlk = *iter; 2617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (curBlk != commonDom) { 2618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org commonDom = findNearestCommonPostDom(curBlk, commonDom); 2619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUGME) { 2623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "Common post dominator for exit blocks is "; 2624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (commonDom) { 2625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "BB" << commonDom->getNumber() << "\n"; 2626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 2627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "NULL\n"; 2628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return commonDom; 2632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //findNearestCommonPostDom 2633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //end namespace llvm 2635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//todo: move-end 2637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===// 2640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// 2641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// CFGStructurizer for AMDGPU 2642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// 2643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===// 2644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgusing namespace llvmCFGStruct; 2647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnamespace llvm 2649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 2650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass AMDGPUCFGStructurizer : public MachineFunctionPass 2651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 2652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpublic: 2653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org typedef MachineInstr InstructionType; 2654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org typedef MachineFunction FunctionType; 2655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org typedef MachineBasicBlock BlockType; 2656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org typedef MachineLoopInfo LoopinfoType; 2657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org typedef MachineDominatorTree DominatortreeType; 2658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org typedef MachinePostDominatorTree PostDominatortreeType; 2659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org typedef MachineDomTreeNode DomTreeNodeType; 2660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org typedef MachineLoop LoopType; 2661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgprotected: 2663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org TargetMachine &TM; 2664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const TargetInstrInfo *TII; 2665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const AMDGPURegisterInfo *TRI; 2666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpublic: 2668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org AMDGPUCFGStructurizer(char &pid, TargetMachine &tm); 2669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const TargetInstrInfo *getTargetInstrInfo() const; 2670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //bool runOnMachineFunction(MachineFunction &F); 2671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgprivate: 2673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; //end of class AMDGPUCFGStructurizer 2675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//char AMDGPUCFGStructurizer::ID = 0; 2677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //end of namespace llvm 2678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgAMDGPUCFGStructurizer::AMDGPUCFGStructurizer(char &pid, TargetMachine &tm 2679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ) 2680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org: MachineFunctionPass(pid), TM(tm), TII(tm.getInstrInfo()), 2681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org TRI(static_cast<const AMDGPURegisterInfo *>(tm.getRegisterInfo()) 2682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ) { 2683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 2684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgconst TargetInstrInfo *AMDGPUCFGStructurizer::getTargetInstrInfo() const { 2686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return TII; 2687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 2688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===// 2689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// 2690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// CFGPrepare 2691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// 2692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===// 2693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgusing namespace llvmCFGStruct; 2696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnamespace llvm 2698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 2699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass AMDGPUCFGPrepare : public AMDGPUCFGStructurizer 2700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 2701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpublic: 2702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static char ID; 2703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpublic: 2705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org AMDGPUCFGPrepare(TargetMachine &tm); 2706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual const char *getPassName() const; 2708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual void getAnalysisUsage(AnalysisUsage &AU) const; 2709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool runOnMachineFunction(MachineFunction &F); 2711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgprivate: 2713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; //end of class AMDGPUCFGPrepare 2715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgchar AMDGPUCFGPrepare::ID = 0; 2717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //end of namespace llvm 2718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgAMDGPUCFGPrepare::AMDGPUCFGPrepare(TargetMachine &tm) 2720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org : AMDGPUCFGStructurizer(ID, tm ) 2721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 2722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 2723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgconst char *AMDGPUCFGPrepare::getPassName() const { 2724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return "AMD IL Control Flow Graph Preparation Pass"; 2725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 2726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid AMDGPUCFGPrepare::getAnalysisUsage(AnalysisUsage &AU) const { 2728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org AU.addPreserved<MachineFunctionAnalysis>(); 2729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org AU.addRequired<MachineFunctionAnalysis>(); 2730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org AU.addRequired<MachineDominatorTree>(); 2731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org AU.addRequired<MachinePostDominatorTree>(); 2732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org AU.addRequired<MachineLoopInfo>(); 2733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 2734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===// 2736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// 2737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// CFGPerform 2738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// 2739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===// 2740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgusing namespace llvmCFGStruct; 2743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnamespace llvm 2745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 2746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass AMDGPUCFGPerform : public AMDGPUCFGStructurizer 2747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 2748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpublic: 2749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static char ID; 2750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpublic: 2752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org AMDGPUCFGPerform(TargetMachine &tm); 2753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual const char *getPassName() const; 2754f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual void getAnalysisUsage(AnalysisUsage &AU) const; 2755f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool runOnMachineFunction(MachineFunction &F); 2756f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2757f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgprivate: 2758f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2759f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; //end of class AMDGPUCFGPerform 2760f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2761f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgchar AMDGPUCFGPerform::ID = 0; 2762f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //end of namespace llvm 2763f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2764f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org AMDGPUCFGPerform::AMDGPUCFGPerform(TargetMachine &tm) 2765f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org: AMDGPUCFGStructurizer(ID, tm) 2766f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 2767f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 2768f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2769f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgconst char *AMDGPUCFGPerform::getPassName() const { 2770f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return "AMD IL Control Flow Graph structurizer Pass"; 2771f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 2772f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2773f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid AMDGPUCFGPerform::getAnalysisUsage(AnalysisUsage &AU) const { 2774f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org AU.addPreserved<MachineFunctionAnalysis>(); 2775f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org AU.addRequired<MachineFunctionAnalysis>(); 2776f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org AU.addRequired<MachineDominatorTree>(); 2777f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org AU.addRequired<MachinePostDominatorTree>(); 2778f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org AU.addRequired<MachineLoopInfo>(); 2779f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 2780f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2781f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===// 2782f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// 2783f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// CFGStructTraits<AMDGPUCFGStructurizer> 2784f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// 2785f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===// 2786f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2787f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnamespace llvmCFGStruct 2788f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 2789f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// this class is tailor to the AMDGPU backend 2790f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<> 2791f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct CFGStructTraits<AMDGPUCFGStructurizer> 2792f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 2793f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org typedef int RegiT; 2794f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2795f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static int getBreakNzeroOpcode(int oldOpcode) { 2796f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch(oldOpcode) { 2797f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case AMDGPU::JUMP: return AMDGPU::BREAK_LOGICALNZ_i32; 2798f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 2799f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(0 && "internal error"); 2800f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org }; 2801f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return -1; 2802f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2803f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2804f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static int getBreakZeroOpcode(int oldOpcode) { 2805f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch(oldOpcode) { 2806f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case AMDGPU::JUMP: return AMDGPU::BREAK_LOGICALZ_i32; 2807f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 2808f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(0 && "internal error"); 2809f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org }; 2810f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return -1; 2811f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2812f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2813f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static int getBranchNzeroOpcode(int oldOpcode) { 2814f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch(oldOpcode) { 2815f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case AMDGPU::JUMP: return AMDGPU::IF_LOGICALNZ_i32; 2816f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ExpandCaseToAllScalarReturn(AMDGPU::BRANCH_COND, AMDGPU::IF_LOGICALNZ); 2817f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case AMDGPU::SI_IF_NZ: return AMDGPU::SI_IF_NZ; 2818f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 2819f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(0 && "internal error"); 2820f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org }; 2821f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return -1; 2822f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2823f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2824f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static int getBranchZeroOpcode(int oldOpcode) { 2825f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch(oldOpcode) { 2826f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case AMDGPU::JUMP: return AMDGPU::IF_LOGICALZ_i32; 2827f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ExpandCaseToAllScalarReturn(AMDGPU::BRANCH_COND, AMDGPU::IF_LOGICALZ); 2828f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case AMDGPU::SI_IF_Z: return AMDGPU::SI_IF_Z; 2829f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 2830f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(0 && "internal error"); 2831f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org }; 2832f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return -1; 2833f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2834f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2835f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static int getContinueNzeroOpcode(int oldOpcode) 2836f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 2837f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch(oldOpcode) { 2838f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case AMDGPU::JUMP: return AMDGPU::CONTINUE_LOGICALNZ_i32; 2839f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 2840f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(0 && "internal error"); 2841f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org }; 2842f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return -1; 2843f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2844f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2845f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static int getContinueZeroOpcode(int oldOpcode) { 2846f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch(oldOpcode) { 2847f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case AMDGPU::JUMP: return AMDGPU::CONTINUE_LOGICALZ_i32; 2848f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 2849f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(0 && "internal error"); 2850f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org }; 2851f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return -1; 2852f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2853f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2854f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// the explicitly represented branch target is the true branch target 2855f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define getExplicitBranch getTrueBranch 2856f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define setExplicitBranch setTrueBranch 2857f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2858f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static MachineBasicBlock *getTrueBranch(MachineInstr *instr) { 2859f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return instr->getOperand(0).getMBB(); 2860f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2861f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2862f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static void setTrueBranch(MachineInstr *instr, MachineBasicBlock *blk) { 2863f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org instr->getOperand(0).setMBB(blk); 2864f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2865f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2866f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static MachineBasicBlock * 2867f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org getFalseBranch(MachineBasicBlock *blk, MachineInstr *instr) { 2868f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(blk->succ_size() == 2); 2869f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org MachineBasicBlock *trueBranch = getTrueBranch(instr); 2870f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org MachineBasicBlock::succ_iterator iter = blk->succ_begin(); 2871f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org MachineBasicBlock::succ_iterator iterNext = iter; 2872f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ++iterNext; 2873f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2874f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return (*iter == trueBranch) ? *iterNext : *iter; 2875f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2876f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2877f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static bool isCondBranch(MachineInstr *instr) { 2878f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch (instr->getOpcode()) { 2879f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case AMDGPU::JUMP: 2880f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return instr->getOperand(instr->findFirstPredOperandIdx()).getReg() != 0; 2881f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ExpandCaseToAllScalarTypes(AMDGPU::BRANCH_COND); 2882f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case AMDGPU::SI_IF_NZ: 2883f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case AMDGPU::SI_IF_Z: 2884f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 2885f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 2886f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return false; 2887f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2888f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return true; 2889f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2890f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2891f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static bool isUncondBranch(MachineInstr *instr) { 2892f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch (instr->getOpcode()) { 2893f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case AMDGPU::JUMP: 2894f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return instr->getOperand(instr->findFirstPredOperandIdx()).getReg() == 0; 2895f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 2896f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return false; 2897f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2898f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return true; 2899f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2900f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2901f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static DebugLoc getLastDebugLocInBB(MachineBasicBlock *blk) { 2902f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //get DebugLoc from the first MachineBasicBlock instruction with debug info 2903f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org DebugLoc DL; 2904f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (MachineBasicBlock::iterator iter = blk->begin(); iter != blk->end(); ++iter) { 2905f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org MachineInstr *instr = &(*iter); 2906f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (instr->getDebugLoc().isUnknown() == false) { 2907f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org DL = instr->getDebugLoc(); 2908f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2909f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2910f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return DL; 2911f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2912f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2913f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static MachineInstr *getNormalBlockBranchInstr(MachineBasicBlock *blk) { 2914f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org MachineBasicBlock::reverse_iterator iter = blk->rbegin(); 2915f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org MachineInstr *instr = &*iter; 2916f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (instr && (isCondBranch(instr) || isUncondBranch(instr))) { 2917f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return instr; 2918f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2919f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 2920f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2921f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2922f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // The correct naming for this is getPossibleLoopendBlockBranchInstr. 2923f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // 2924f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // BB with backward-edge could have move instructions after the branch 2925f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // instruction. Such move instruction "belong to" the loop backward-edge. 2926f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // 2927f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static MachineInstr *getLoopendBlockBranchInstr(MachineBasicBlock *blk) { 2928f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const AMDGPUInstrInfo * TII = static_cast<const AMDGPUInstrInfo *>( 2929f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org blk->getParent()->getTarget().getInstrInfo()); 2930f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2931f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (MachineBasicBlock::reverse_iterator iter = blk->rbegin(), 2932f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org iterEnd = blk->rend(); iter != iterEnd; ++iter) { 2933f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // FIXME: Simplify 2934f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org MachineInstr *instr = &*iter; 2935f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (instr) { 2936f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (isCondBranch(instr) || isUncondBranch(instr)) { 2937f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return instr; 2938f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (!TII->isMov(instr->getOpcode())) { 2939f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 2940f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2941f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2942f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2943f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 2944f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2945f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2946f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static MachineInstr *getReturnInstr(MachineBasicBlock *blk) { 2947f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org MachineBasicBlock::reverse_iterator iter = blk->rbegin(); 2948f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (iter != blk->rend()) { 2949f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org MachineInstr *instr = &(*iter); 2950f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (instr->getOpcode() == AMDGPU::RETURN) { 2951f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return instr; 2952f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2953f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2954f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 2955f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2956f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2957f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static MachineInstr *getContinueInstr(MachineBasicBlock *blk) { 2958f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org MachineBasicBlock::reverse_iterator iter = blk->rbegin(); 2959f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (iter != blk->rend()) { 2960f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org MachineInstr *instr = &(*iter); 2961f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (instr->getOpcode() == AMDGPU::CONTINUE) { 2962f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return instr; 2963f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2964f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2965f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 2966f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2967f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2968f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static MachineInstr *getLoopBreakInstr(MachineBasicBlock *blk) { 2969f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (MachineBasicBlock::iterator iter = blk->begin(); (iter != blk->end()); ++iter) { 2970f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org MachineInstr *instr = &(*iter); 2971f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ((instr->getOpcode() == AMDGPU::BREAK_LOGICALNZ_i32) || (instr->getOpcode() == AMDGPU::BREAK_LOGICALZ_i32)) { 2972f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return instr; 2973f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2974f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2975f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 2976f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2977f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2978f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static bool isReturnBlock(MachineBasicBlock *blk) { 2979f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org MachineInstr *instr = getReturnInstr(blk); 2980f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool isReturn = (blk->succ_size() == 0); 2981f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (instr) { 2982f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(isReturn); 2983f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (isReturn) { 2984f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (DEBUGME) { 2985f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org errs() << "BB" << blk->getNumber() 2986f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org <<" is return block without RETURN instr\n"; 2987f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2988f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2989f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2990f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return isReturn; 2991f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2992f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2993f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static MachineBasicBlock::iterator 2994f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org getInstrPos(MachineBasicBlock *blk, MachineInstr *instr) { 2995f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(instr->getParent() == blk && "instruction doesn't belong to block"); 2996f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org MachineBasicBlock::iterator iter = blk->begin(); 2997f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org MachineBasicBlock::iterator iterEnd = blk->end(); 2998f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org while (&(*iter) != instr && iter != iterEnd) { 2999f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ++iter; 3000f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3001f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3002f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(iter != iterEnd); 3003f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return iter; 3004f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org }//getInstrPos 3005f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3006f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static MachineInstr *insertInstrBefore(MachineBasicBlock *blk, int newOpcode, 3007f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org AMDGPUCFGStructurizer *passRep) { 3008f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return insertInstrBefore(blk,newOpcode,passRep,DebugLoc()); 3009f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } //insertInstrBefore 3010f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3011f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static MachineInstr *insertInstrBefore(MachineBasicBlock *blk, int newOpcode, 3012f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org AMDGPUCFGStructurizer *passRep, DebugLoc DL) { 3013f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const TargetInstrInfo *tii = passRep->getTargetInstrInfo(); 3014f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org MachineInstr *newInstr = 3015f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org blk->getParent()->CreateMachineInstr(tii->get(newOpcode), DL); 3016f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3017f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org MachineBasicBlock::iterator res; 3018f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (blk->begin() != blk->end()) { 3019f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org blk->insert(blk->begin(), newInstr); 3020f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 3021f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org blk->push_back(newInstr); 3022f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3023f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3024f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SHOWNEWINSTR(newInstr); 3025f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3026f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return newInstr; 3027f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } //insertInstrBefore 3028f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3029f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static void insertInstrEnd(MachineBasicBlock *blk, int newOpcode, 3030f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org AMDGPUCFGStructurizer *passRep) { 3031f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org insertInstrEnd(blk,newOpcode,passRep,DebugLoc()); 3032f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } //insertInstrEnd 3033f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3034f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static void insertInstrEnd(MachineBasicBlock *blk, int newOpcode, 3035f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org AMDGPUCFGStructurizer *passRep, DebugLoc DL) { 3036f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const TargetInstrInfo *tii = passRep->getTargetInstrInfo(); 3037f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org MachineInstr *newInstr = blk->getParent() 3038f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ->CreateMachineInstr(tii->get(newOpcode), DL); 3039f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3040f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org blk->push_back(newInstr); 3041f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //assume the instruction doesn't take any reg operand ... 3042f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3043f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SHOWNEWINSTR(newInstr); 3044f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } //insertInstrEnd 3045f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3046f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static MachineInstr *insertInstrBefore(MachineBasicBlock::iterator instrPos, 3047f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int newOpcode, 3048f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org AMDGPUCFGStructurizer *passRep) { 3049f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org MachineInstr *oldInstr = &(*instrPos); 3050f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const TargetInstrInfo *tii = passRep->getTargetInstrInfo(); 3051f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org MachineBasicBlock *blk = oldInstr->getParent(); 3052f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org MachineInstr *newInstr = 3053f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org blk->getParent()->CreateMachineInstr(tii->get(newOpcode), 3054f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org DebugLoc()); 3055f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3056f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org blk->insert(instrPos, newInstr); 3057f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //assume the instruction doesn't take any reg operand ... 3058f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3059f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SHOWNEWINSTR(newInstr); 3060f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return newInstr; 3061f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } //insertInstrBefore 3062f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3063f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static void insertCondBranchBefore(MachineBasicBlock::iterator instrPos, 3064f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int newOpcode, 3065f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org AMDGPUCFGStructurizer *passRep, 3066f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org DebugLoc DL) { 3067f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org MachineInstr *oldInstr = &(*instrPos); 3068f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const TargetInstrInfo *tii = passRep->getTargetInstrInfo(); 3069f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org MachineBasicBlock *blk = oldInstr->getParent(); 3070f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org MachineInstr *newInstr = 3071f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org blk->getParent()->CreateMachineInstr(tii->get(newOpcode), 3072f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org DL); 3073f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3074f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org blk->insert(instrPos, newInstr); 3075f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org MachineInstrBuilder(newInstr).addReg(oldInstr->getOperand(1).getReg(), 3076f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org false); 3077f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3078f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SHOWNEWINSTR(newInstr); 3079f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //erase later oldInstr->eraseFromParent(); 3080f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } //insertCondBranchBefore 3081f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3082f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static void insertCondBranchBefore(MachineBasicBlock *blk, 3083f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org MachineBasicBlock::iterator insertPos, 3084f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int newOpcode, 3085f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org AMDGPUCFGStructurizer *passRep, 3086f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RegiT regNum, 3087f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org DebugLoc DL) { 3088f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const TargetInstrInfo *tii = passRep->getTargetInstrInfo(); 3089f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3090f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org MachineInstr *newInstr = 3091f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org blk->getParent()->CreateMachineInstr(tii->get(newOpcode), DL); 3092f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3093f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //insert before 3094f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org blk->insert(insertPos, newInstr); 3095f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org MachineInstrBuilder(newInstr).addReg(regNum, false); 3096f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3097f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SHOWNEWINSTR(newInstr); 3098f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } //insertCondBranchBefore 3099f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static void insertCondBranchEnd(MachineBasicBlock *blk, 3101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int newOpcode, 3102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org AMDGPUCFGStructurizer *passRep, 3103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RegiT regNum) { 3104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const TargetInstrInfo *tii = passRep->getTargetInstrInfo(); 3105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org MachineInstr *newInstr = 3106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org blk->getParent()->CreateMachineInstr(tii->get(newOpcode), DebugLoc()); 3107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org blk->push_back(newInstr); 3109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org MachineInstrBuilder(newInstr).addReg(regNum, false); 3110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SHOWNEWINSTR(newInstr); 3112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } //insertCondBranchEnd 3113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static void insertAssignInstrBefore(MachineBasicBlock::iterator instrPos, 3116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org AMDGPUCFGStructurizer *passRep, 3117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RegiT regNum, int regVal) { 3118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org MachineInstr *oldInstr = &(*instrPos); 3119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const AMDGPUInstrInfo *tii = 3120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static_cast<const AMDGPUInstrInfo *>(passRep->getTargetInstrInfo()); 3121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org MachineBasicBlock *blk = oldInstr->getParent(); 3122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org MachineInstr *newInstr = tii->getMovImmInstr(blk->getParent(), regNum, 3123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org regVal); 3124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org blk->insert(instrPos, newInstr); 3125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SHOWNEWINSTR(newInstr); 3127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } //insertAssignInstrBefore 3128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static void insertAssignInstrBefore(MachineBasicBlock *blk, 3130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org AMDGPUCFGStructurizer *passRep, 3131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RegiT regNum, int regVal) { 3132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const AMDGPUInstrInfo *tii = 3133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static_cast<const AMDGPUInstrInfo *>(passRep->getTargetInstrInfo()); 3134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org MachineInstr *newInstr = tii->getMovImmInstr(blk->getParent(), regNum, 3136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org regVal); 3137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (blk->begin() != blk->end()) { 3138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org blk->insert(blk->begin(), newInstr); 3139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 3140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org blk->push_back(newInstr); 3141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SHOWNEWINSTR(newInstr); 3144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } //insertInstrBefore 3146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static void insertCompareInstrBefore(MachineBasicBlock *blk, 3148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org MachineBasicBlock::iterator instrPos, 3149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org AMDGPUCFGStructurizer *passRep, 3150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RegiT dstReg, RegiT src1Reg, 3151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RegiT src2Reg) { 3152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const AMDGPUInstrInfo *tii = 3153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static_cast<const AMDGPUInstrInfo *>(passRep->getTargetInstrInfo()); 3154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org MachineInstr *newInstr = 3155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org blk->getParent()->CreateMachineInstr(tii->get(tii->getIEQOpcode()), DebugLoc()); 3156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org MachineInstrBuilder(newInstr).addReg(dstReg, RegState::Define); //set target 3158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org MachineInstrBuilder(newInstr).addReg(src1Reg); //set src value 3159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org MachineInstrBuilder(newInstr).addReg(src2Reg); //set src value 3160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org blk->insert(instrPos, newInstr); 3162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SHOWNEWINSTR(newInstr); 3163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } //insertCompareInstrBefore 3165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static void cloneSuccessorList(MachineBasicBlock *dstBlk, 3167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org MachineBasicBlock *srcBlk) { 3168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (MachineBasicBlock::succ_iterator iter = srcBlk->succ_begin(), 3169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org iterEnd = srcBlk->succ_end(); iter != iterEnd; ++iter) { 3170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dstBlk->addSuccessor(*iter); // *iter's predecessor is also taken care of 3171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } //cloneSuccessorList 3173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static MachineBasicBlock *clone(MachineBasicBlock *srcBlk) { 3175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org MachineFunction *func = srcBlk->getParent(); 3176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org MachineBasicBlock *newBlk = func->CreateMachineBasicBlock(); 3177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org func->push_back(newBlk); //insert to function 3178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //newBlk->setNumber(srcBlk->getNumber()); 3179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (MachineBasicBlock::iterator iter = srcBlk->begin(), 3180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org iterEnd = srcBlk->end(); 3181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org iter != iterEnd; ++iter) { 3182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org MachineInstr *instr = func->CloneMachineInstr(iter); 3183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org newBlk->push_back(instr); 3184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return newBlk; 3186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //MachineBasicBlock::ReplaceUsesOfBlockWith doesn't serve the purpose because 3189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //the AMDGPU instruction is not recognized as terminator fix this and retire 3190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //this routine 3191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static void replaceInstrUseOfBlockWith(MachineBasicBlock *srcBlk, 3192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org MachineBasicBlock *oldBlk, 3193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org MachineBasicBlock *newBlk) { 3194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org MachineInstr *branchInstr = getLoopendBlockBranchInstr(srcBlk); 3195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (branchInstr && isCondBranch(branchInstr) && 3196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org getExplicitBranch(branchInstr) == oldBlk) { 3197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org setExplicitBranch(branchInstr, newBlk); 3198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static void wrapup(MachineBasicBlock *entryBlk) { 3202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert((!entryBlk->getParent()->getJumpTableInfo() 3203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org || entryBlk->getParent()->getJumpTableInfo()->isEmpty()) 3204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && "found a jump table"); 3205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //collect continue right before endloop 3207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SmallVector<MachineInstr *, DEFAULT_VEC_SLOTS> contInstr; 3208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org MachineBasicBlock::iterator pre = entryBlk->begin(); 3209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org MachineBasicBlock::iterator iterEnd = entryBlk->end(); 3210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org MachineBasicBlock::iterator iter = pre; 3211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org while (iter != iterEnd) { 3212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (pre->getOpcode() == AMDGPU::CONTINUE 3213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && iter->getOpcode() == AMDGPU::ENDLOOP) { 3214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org contInstr.push_back(pre); 3215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pre = iter; 3217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ++iter; 3218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } //end while 3219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org //delete continue right before endloop 3221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (unsigned i = 0; i < contInstr.size(); ++i) { 3222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org contInstr[i]->eraseFromParent(); 3223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // TODO to fix up jump table so later phase won't be confused. if 3226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // (jumpTableInfo->isEmpty() == false) { need to clean the jump table, but 3227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // there isn't such an interface yet. alternatively, replace all the other 3228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // blocks in the jump table with the entryBlk //} 3229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } //wrapup 3231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static MachineDominatorTree *getDominatorTree(AMDGPUCFGStructurizer &pass) { 3233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return &pass.getAnalysis<MachineDominatorTree>(); 3234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static MachinePostDominatorTree* 3237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org getPostDominatorTree(AMDGPUCFGStructurizer &pass) { 3238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return &pass.getAnalysis<MachinePostDominatorTree>(); 3239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static MachineLoopInfo *getLoopInfo(AMDGPUCFGStructurizer &pass) { 3242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return &pass.getAnalysis<MachineLoopInfo>(); 3243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; // template class CFGStructTraits 3245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //end of namespace llvm 3246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// createAMDGPUCFGPreparationPass- Returns a pass 3248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgFunctionPass *llvm::createAMDGPUCFGPreparationPass(TargetMachine &tm 3249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ) { 3250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return new AMDGPUCFGPrepare(tm ); 3251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 3252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool AMDGPUCFGPrepare::runOnMachineFunction(MachineFunction &func) { 3254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return llvmCFGStruct::CFGStructurizer<AMDGPUCFGStructurizer>().prepare(func, 3255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *this, 3256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org TRI); 3257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 3258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// createAMDGPUCFGStructurizerPass- Returns a pass 3260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgFunctionPass *llvm::createAMDGPUCFGStructurizerPass(TargetMachine &tm 3261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ) { 3262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return new AMDGPUCFGPerform(tm ); 3263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 3264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool AMDGPUCFGPerform::runOnMachineFunction(MachineFunction &func) { 3266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return llvmCFGStruct::CFGStructurizer<AMDGPUCFGStructurizer>().run(func, 3267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *this, 3268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org TRI); 3269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 3270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//end of file newline goes below 3272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3273