[llvm-commits] CVS: llvm/lib/Target/SparcV9/ModuloScheduling/ModuloSchedulingSuperBlock.cpp ModuloSchedulingSuperBlock.h

Tanya Brethour tbrethou at cs.uiuc.edu
Sat Apr 30 18:27:59 PDT 2005



Changes in directory llvm/lib/Target/SparcV9/ModuloScheduling:

ModuloSchedulingSuperBlock.cpp added (r1.1)
ModuloSchedulingSuperBlock.h added (r1.1)
---
Log message:

SMS for superblocks.


---
Diffs of the changes:  (+379 -0)

 ModuloSchedulingSuperBlock.cpp |  282 +++++++++++++++++++++++++++++++++++++++++
 ModuloSchedulingSuperBlock.h   |   97 ++++++++++++++
 2 files changed, 379 insertions(+)


Index: llvm/lib/Target/SparcV9/ModuloScheduling/ModuloSchedulingSuperBlock.cpp
diff -c /dev/null llvm/lib/Target/SparcV9/ModuloScheduling/ModuloSchedulingSuperBlock.cpp:1.1
*** /dev/null	Sat Apr 30 20:27:57 2005
--- llvm/lib/Target/SparcV9/ModuloScheduling/ModuloSchedulingSuperBlock.cpp	Sat Apr 30 20:27:47 2005
***************
*** 0 ****
--- 1,282 ----
+ //===-- ModuloSchedulingSuperBlock.cpp - ModuloScheduling--------*- 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.
+ //
+ //===----------------------------------------------------------------------===//
+ //
+ //  This ModuloScheduling pass is based on the Swing Modulo Scheduling
+ //  algorithm, but has been extended to support SuperBlocks (multiple
+ //  basic block, single entry, multipl exit loops).
+ //
+ //===----------------------------------------------------------------------===//
+ 
+ #define DEBUG_TYPE "ModuloSchedSB"
+ 
+ #include "DependenceAnalyzer.h"
+ #include "ModuloSchedulingSuperBlock.h"
+ #include "llvm/ADT/Statistic.h"
+ #include "llvm/CodeGen/MachineFunction.h"
+ #include "llvm/CodeGen/Passes.h"
+ #include "llvm/Support/CFG.h"
+ #include "llvm/Support/Debug.h"
+ #include "llvm/Support/GraphWriter.h"
+ #include "llvm/Instructions.h"
+ #include "../MachineCodeForInstruction.h"
+ #include "../SparcV9RegisterInfo.h"
+ #include "../SparcV9Internals.h"
+ #include "../SparcV9TmpInstr.h"
+ #include <fstream>
+ #include <sstream>
+ 
+ using namespace llvm;
+ /// Create ModuloSchedulingSBPass
+ ///
+ FunctionPass *llvm::createModuloSchedulingSBPass(TargetMachine & targ) {
+   DEBUG(std::cerr << "Created ModuloSchedulingSBPass\n");
+   return new ModuloSchedulingSBPass(targ);
+ }
+ 
+ //Graph Traits for printing out the dependence graph
+ template<typename GraphType>
+ static void WriteGraphToFile(std::ostream &O, const std::string &GraphName,
+                              const GraphType &GT) {
+   std::string Filename = GraphName + ".dot";
+   O << "Writing '" << Filename << "'...";
+   std::ofstream F(Filename.c_str());
+ 
+   if (F.good())
+     WriteGraph(F, GT);
+   else
+     O << "  error opening file for writing!";
+   O << "\n";
+ };
+ 
+ namespace llvm {
+   Statistic<> NumLoops("moduloschedSB-numLoops", "Total Number of Loops");
+   Statistic<> NumSB("moduloschedSB-numSuperBlocks", "Total Number of SuperBlocks");
+   Statistic<> BBWithCalls("modulosched-BBCalls", "Basic Blocks rejected due to calls");
+   Statistic<> BBWithCondMov("modulosched-loopCondMov", "Basic Blocks rejected due to conditional moves");
+   bool ModuloSchedulingSBPass::runOnFunction(Function &F) {
+     bool Changed = false;
+     
+     //Get MachineFunction
+     MachineFunction &MF = MachineFunction::get(&F);
+ 
+     //Get Loop Info & Dependence Anaysis info
+     LoopInfo &LI = getAnalysis<LoopInfo>();
+     DependenceAnalyzer &DA = getAnalysis<DependenceAnalyzer>();
+ 
+     //Worklist of superblocks
+     std::vector<std::vector<const MachineBasicBlock*> > Worklist;
+     FindSuperBlocks(F, LI, Worklist);
+  
+     DEBUG(if(Worklist.size() == 0) std::cerr << "No superblocks in function to ModuloSchedule\n");
+     
+     //Loop over worklist and ModuloSchedule each SuperBlock
+     for(std::vector<std::vector<const MachineBasicBlock*> >::iterator SB = Worklist.begin(),
+ 	  SBE = Worklist.end(); SB != SBE; ++SB) {
+       
+       //Print out Superblock
+       DEBUG(std::cerr << "ModuloScheduling SB: \n";
+ 	    for(std::vector<const MachineBasicBlock*>::const_iterator BI = SB->begin(), 
+ 		  BE = SB->end(); BI != BE; ++BI) {
+ 	      (*BI)->print(std::cerr);});
+       
+       if(!CreateDefMap(*SB)) {
+ 	defaultInst = 0;
+ 	defMap.clear();
+ 	continue;
+       }
+ 
+       MSchedGraph *MSG = new MSchedGraph(*SB, target, indVarInstrs[*SB], DA, 
+ 					 machineTollvm[*SB]);
+ 
+       //Write Graph out to file
+       DEBUG(WriteGraphToFile(std::cerr, F.getName(), MSG));
+       DEBUG(MSG->print(std::cerr));
+ 
+     }
+     return Changed;
+     
+   }
+ 
+   void ModuloSchedulingSBPass::FindSuperBlocks(Function &F, LoopInfo &LI,
+ 		      std::vector<std::vector<const MachineBasicBlock*> > &Worklist) {
+ 
+     //Get MachineFunction
+     MachineFunction &MF = MachineFunction::get(&F);
+     
+     //Map of LLVM BB to machine BB
+     std::map<BasicBlock*, MachineBasicBlock*> bbMap;
+ 
+     for (MachineFunction::iterator BI = MF.begin(); BI != MF.end(); ++BI) {
+       BasicBlock *llvmBB = (BasicBlock*) BI->getBasicBlock();
+       assert(!bbMap.count(llvmBB) && "LLVM BB already in map!");
+       bbMap[llvmBB] = &*BI;
+     }
+ 
+     //Iterate over the loops, and find super blocks
+     for(LoopInfo::iterator LB = LI.begin(), LE = LI.end(); LB != LE; ++LB) {
+       Loop *L = *LB;
+       ++NumLoops;
+ 
+       //If loop is not single entry, try the next one
+       if(!L->getLoopPreheader())
+ 	continue;
+     
+       //Check size of this loop, we don't want SBB loops
+       if(L->getBlocks().size() == 1)
+ 	continue;
+       
+       //Check if this loop contains no sub loops
+       if(L->getSubLoops().size() == 0) {
+ 	
+ 	std::vector<const MachineBasicBlock*> superBlock;
+ 	
+ 	//Get Loop Headers
+ 	BasicBlock *header = L->getHeader();
+ 
+ 	//Follow the header and make sure each BB only has one entry and is valid
+ 	BasicBlock *current = header;
+ 	assert(bbMap.count(current) && "LLVM BB must have corresponding Machine BB\n");
+ 	MachineBasicBlock *currentMBB = bbMap[header];
+ 	bool done = false;
+ 	bool success = true;
+ 
+ 	while(!done) {
+ 	  
+ 	  if(MachineBBisValid(currentMBB)) {
+ 
+ 	    //Loop over successors of this BB, they should be in the loop block
+ 	    //and be valid
+ 	    BasicBlock *next = 0;
+ 	    for(succ_iterator I = succ_begin(current), E = succ_end(current);
+ 		I != E; ++I) {
+ 	      if(L->contains(*I)) {
+ 		if(!next) 
+ 		  next = *I;
+ 		else {
+ 		  done = true;
+ 		  success = false;
+ 		  break;
+ 		}
+ 	      }
+ 	    }
+ 	    if(success) {
+ 	      superBlock.push_back(currentMBB);
+ 	      if(next == header)
+ 		done = true;
+ 	      else if(!next->getSinglePredecessor()) {
+ 		done = true;
+ 		success = false;
+ 	      }
+ 	      else {
+ 		//Check that the next BB only has one entry
+ 		current = next;
+ 		assert(bbMap.count(current) && "LLVM BB must have corresponding Machine BB");
+ 		currentMBB = bbMap[current];
+ 	      }
+ 	    }
+ 	  }
+ 	  else {
+ 	    done = true;
+ 	    success = false;
+ 	  }
+ 	}
+ 
+ 	if(success) {
+ 	  ++NumSB;
+ 	  Worklist.push_back(superBlock);
+ 	}
+ 
+       }
+ 
+     }
+   }
+   
+   /// This function checks if a Machine Basic Block is valid for modulo
+   /// scheduling. This means that it has no control flow (if/else or
+   /// calls) in the block.  Currently ModuloScheduling only works on
+   /// single basic block loops.
+   bool ModuloSchedulingSBPass::MachineBBisValid(const MachineBasicBlock *BI) {
+     
+     //Check size of our basic block.. make sure we have more then just the terminator in it
+     if(BI->getBasicBlock()->size() == 1)
+       return false;
+     
+     //Get Target machine instruction info
+     const TargetInstrInfo *TMI = target.getInstrInfo();
+ 
+     //Check each instruction and look for calls, keep map to get index later
+     std::map<const MachineInstr*, unsigned> indexMap;
+ 
+     unsigned count = 0;
+     for(MachineBasicBlock::const_iterator I = BI->begin(), E = BI->end(); I != E; ++I) {
+       //Get opcode to check instruction type
+       MachineOpCode OC = I->getOpcode();
+ 
+       //Look for calls
+       if(TMI->isCall(OC)) {
+ 	++BBWithCalls;
+ 	return false;
+       }
+     
+       //Look for conditional move
+       if(OC == V9::MOVRZr || OC == V9::MOVRZi || OC == V9::MOVRLEZr || OC == V9::MOVRLEZi
+ 	 || OC == V9::MOVRLZr || OC == V9::MOVRLZi || OC == V9::MOVRNZr || OC == V9::MOVRNZi
+ 	 || OC == V9::MOVRGZr || OC == V9::MOVRGZi || OC == V9::MOVRGEZr
+ 	 || OC == V9::MOVRGEZi || OC == V9::MOVLEr || OC == V9::MOVLEi || OC == V9::MOVLEUr
+ 	 || OC == V9::MOVLEUi || OC == V9::MOVFLEr || OC == V9::MOVFLEi
+ 	 || OC == V9::MOVNEr || OC == V9::MOVNEi || OC == V9::MOVNEGr || OC == V9::MOVNEGi
+ 	 || OC == V9::MOVFNEr || OC == V9::MOVFNEi) {
+ 	++BBWithCondMov;
+ 	return false;
+       }
+ 
+       indexMap[I] = count;
+ 
+       if(TMI->isNop(OC))
+ 	continue;
+ 
+       ++count;
+     }
+ 
+     return true;
+   }
+ }
+ 
+ bool ModuloSchedulingSBPass::CreateDefMap(std::vector<const MachineBasicBlock*> &SB) {
+   defaultInst = 0;
+ 
+   for(std::vector<const MachineBasicBlock*>::iterator BI = SB.begin(), 
+ 	BE = SB.end(); BI != BE; ++BI) {
+ 
+     for(MachineBasicBlock::const_iterator I = (*BI)->begin(), E = (*BI)->end(); I != E; ++I) {
+       for(unsigned opNum = 0; opNum < I->getNumOperands(); ++opNum) {
+ 	const MachineOperand &mOp = I->getOperand(opNum);
+ 	if(mOp.getType() == MachineOperand::MO_VirtualRegister && mOp.isDef()) {
+ 	  
+ 	  //assert if this is the second def we have seen
+ 	  assert(!defMap.count(mOp.getVRegValue()) && "Def already in the map");
+ 	  defMap[mOp.getVRegValue()] = (MachineInstr*) &*I;
+ 	}
+ 	
+ 	//See if we can use this Value* as our defaultInst
+ 	if(!defaultInst && mOp.getType() == MachineOperand::MO_VirtualRegister) {
+ 	  Value *V = mOp.getVRegValue();
+ 	  if(!isa<TmpInstruction>(V) && !isa<Argument>(V) && !isa<Constant>(V) && !isa<PHINode>(V))
+ 	    defaultInst = (Instruction*) V;
+ 	}
+       }
+     }
+   }
+     
+   if(!defaultInst)
+     return false;
+   
+   return true;
+ 
+ }


Index: llvm/lib/Target/SparcV9/ModuloScheduling/ModuloSchedulingSuperBlock.h
diff -c /dev/null llvm/lib/Target/SparcV9/ModuloScheduling/ModuloSchedulingSuperBlock.h:1.1
*** /dev/null	Sat Apr 30 20:27:59 2005
--- llvm/lib/Target/SparcV9/ModuloScheduling/ModuloSchedulingSuperBlock.h	Sat Apr 30 20:27:47 2005
***************
*** 0 ****
--- 1,97 ----
+ //===-- 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/Function.h"
+ #include "llvm/Pass.h"
+ #include "llvm/CodeGen/MachineBasicBlock.h"
+ #include "MSSchedule.h"
+ #include "MSchedGraph.h"
+ 
+ namespace llvm {
+ 
+   //Struct to contain ModuloScheduling Specific Information for each node
+   struct MSNodeAttributes {
+     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;
+     MSNodeAttributes(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<const MachineBasicBlock*> SuperBlock;
+ 
+   class ModuloSchedulingSBPass : public FunctionPass {
+     const TargetMachine ⌖
+     
+     //Map to hold Value* defs
+     std::map<const Value*, MachineInstr*> defMap;
+ 
+     //Map to hold list of instructions associate to the induction var for each BB
+     std::map<SuperBlock, std::map<const MachineInstr*, unsigned> > indVarInstrs;
+ 
+     //Map to hold machine to  llvm instrs for each valid BB
+     std::map<SuperBlock, std::map<MachineInstr*, Instruction*> > machineTollvm;
+     
+     //LLVM Instruction we know we can add TmpInstructions to its MCFI
+     Instruction *defaultInst;
+ 
+     //Map that holds node to node attribute information
+     std::map<MSchedGraphNode*, MSNodeAttributes> nodeToAttributesMap;
+ 
+     //Map to hold all reccurrences
+     std::set<std::pair<int, std::vector<MSchedGraphNode*> > > recurrenceList;
+ 
+     //Set of edges to ignore, stored as src node and index into vector of successors
+     std::set<std::pair<MSchedGraphNode*, unsigned> > edgesToIgnore;
+ 
+     //Vector containing the partial order
+     std::vector<std::set<MSchedGraphNode*> > partialOrder;
+ 
+     //Vector containing the final node order
+     std::vector<MSchedGraphNode*> FinalNodeOrder;
+ 
+     //Schedule table, key is the cycle number and the vector is resource, node pairs
+     MSSchedule schedule;
+ 
+     //Current initiation interval
+     int II;
+     
+     //Internal Functions
+     void FindSuperBlocks(Function &F, LoopInfo &LI, 
+ 			 std::vector<std::vector<const MachineBasicBlock*> > &Worklist);
+     bool MachineBBisValid(const MachineBasicBlock *B);
+     bool CreateDefMap(std::vector<const MachineBasicBlock*> &SB);
+ 
+   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 {
+ 	AU.addRequired<LoopInfo>();
+ 	AU.addRequired<DependenceAnalyzer>();
+       }
+   };
+ }
+ #endif






More information about the llvm-commits mailing list