//===-- ModuloSchedulingSuperBlock.h -Swing Modulo Scheduling-----*- C++ -*-===// // // The LLVM Compiler Infrastructure // // This file was developed by the LLVM research group and is distributed under // the University of Illinois Open Source License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// //Swing Modulo Scheduling done on Superblocks ( entry, multiple exit, //multiple basic block loops). // //===----------------------------------------------------------------------===// #ifndef LLVM_MODULOSCHEDULINGSB_H #define LLVM_MODULOSCHEDULINGSB_H #include "llvm/Analysis/LoopInfo.h" #include "llvm/Analysis/ScalarEvolution.h" #include "llvm/Function.h" #include "llvm/Pass.h" #include "llvm/CodeGen/MachineBasicBlock.h" #include "MSScheduleSB.h" #include "MSchedGraphSB.h" namespace llvm { //Struct to contain ModuloScheduling Specific Information for each node struct MSNodeSBAttributes { int ASAP; //Earliest time at which the opreation can be scheduled int ALAP; //Latest time at which the operation can be scheduled. int MOB; int depth; int height; MSNodeSBAttributes(int asap=-1, int alap=-1, int mob=-1, int d=-1, int h=-1) : ASAP(asap), ALAP(alap), MOB(mob), depth(d), height(h) {} }; typedef std::vector SuperBlock; class ModuloSchedulingSBPass : public FunctionPass { const TargetMachine ⌖ //Map to hold Value* defs std::map defMap; //Map to hold list of instructions associate to the induction var for each BB std::map > indVarInstrs; //Map to hold machine to llvm instrs for each valid BB std::map > machineTollvm; //LLVM Instruction we know we can add TmpInstructions to its MCFI Instruction *defaultInst; //Map that holds node to node attribute information std::map nodeToAttributesMap; //Map to hold all reccurrences std::set > > recurrenceList; //Set of edges to ignore, stored as src node and index into vector of successors std::set > edgesToIgnore; //Vector containing the partial order std::vector > partialOrder; //Vector containing the final node order std::vector FinalNodeOrder; //Schedule table, key is the cycle number and the vector is resource, node pairs MSScheduleSB schedule; //Current initiation interval int II; //Internal Functions void FindSuperBlocks(Function &F, LoopInfo &LI, std::vector > &Worklist); bool MachineBBisValid(const MachineBasicBlock *B, std::map &indexMap, unsigned &offset); bool CreateDefMap(std::vector &SB); bool getIndVar(std::vector &superBlock, std::map &bbMap, std::map &indexMap); bool assocIndVar(Instruction *I, std::set &indVar, std::vector &stack, std::map &bbMap, const BasicBlock *first, std::set &llvmSuperBlock); int calculateResMII(std::vector &superBlock); int calculateRecMII(MSchedGraphSB *graph, int MII); void findAllCircuits(MSchedGraphSB *g, int II); void addRecc(std::vector &stack, std::map &newNodes); bool circuit(MSchedGraphSBNode *v, std::vector &stack, std::set &blocked, std::vector &SCC, MSchedGraphSBNode *s, std::map > &B, int II, std::map &newNodes); void unblock(MSchedGraphSBNode *u, std::set &blocked, std::map > &B); void addSCC(std::vector &SCC, std::map &newNodes); void calculateNodeAttributes(MSchedGraphSB *graph, int MII); bool ignoreEdge(MSchedGraphSBNode *srcNode, MSchedGraphSBNode *destNode); int calculateASAP(MSchedGraphSBNode *node, int MII, MSchedGraphSBNode *destNode); int calculateALAP(MSchedGraphSBNode *node, int MII, int maxASAP, MSchedGraphSBNode *srcNode); int findMaxASAP(); int calculateHeight(MSchedGraphSBNode *node,MSchedGraphSBNode *srcNode); int calculateDepth(MSchedGraphSBNode *node, MSchedGraphSBNode *destNode); void computePartialOrder(); void connectedComponentSet(MSchedGraphSBNode *node, std::set &ccSet, std::set &lastNodes); void searchPath(MSchedGraphSBNode *node, std::vector &path, std::set &nodesToAdd, std::set &new_reccurrence); void orderNodes(); bool computeSchedule(std::vector &BB, MSchedGraphSB *MSG); bool scheduleNode(MSchedGraphSBNode *node, int start, int end); void predIntersect(std::set &CurrentSet, std::set &IntersectResult); void succIntersect(std::set &CurrentSet, std::set &IntersectResult); void reconstructLoop(std::vector &SB); void fixBranches(std::vector > &prologues, std::vector > &llvm_prologues, std::vector &machineKernelBB, std::vector &llvmKernelBB, std::vector > &epilogues, std::vector > &llvm_epilogues, std::vector &SB, std::map &sideExits); void writePrologues(std::vector > &prologues, std::vector &origBB, std::vector > &llvm_prologues, std::map > &valuesToSave, std::map > &newValues, std::map &newValLocation); void writeKernel(std::vector &llvmBB, std::vector &machineBB, std::map > &valuesToSave, std::map > &newValues, std::map &newValLocation, std::map > &kernelPHIs); void removePHIs(std::vector &SB, std::vector > &prologues, std::vector > &epilogues, std::vector &kernelBB, std::map &newValLocation); void writeEpilogues(std::vector > &epilogues, std::vector &origSB, std::vector > &llvm_epilogues, std::map > &valuesToSave, std::map > &newValues, std::map &newValLocation, std::map > &kernelPHIs); void writeSideExits(std::vector > &prologues, std::vector > &llvm_prologues, std::vector > &epilogues, std::vector > &llvm_epilogues, std::map &sideExits, std::map > > &instrsMovedDown, std::vector &SB, std::vector &kernelMBBs, std::map branchStage); public: ModuloSchedulingSBPass(TargetMachine &targ) : target(targ) {} virtual bool runOnFunction(Function &F); virtual const char* getPassName() const { return "ModuloScheduling-SuperBlock"; } // getAnalysisUsage virtual void getAnalysisUsage(AnalysisUsage &AU) const { /// HACK: We don't actually need scev, but we have /// to say we do so that the pass manager does not delete it /// before we run. AU.addRequired(); AU.addRequired(); AU.addRequired(); } }; } #endif