Compare dependence analysis with llvm instructions versus machine instrutions. the...
authorTanya Lattner <tonic@nondot.org>
Tue, 29 Mar 2005 20:35:10 +0000 (20:35 +0000)
committerTanya Lattner <tonic@nondot.org>
Tue, 29 Mar 2005 20:35:10 +0000 (20:35 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@20931 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/SparcV9/ModuloScheduling/MSchedGraph.cpp
lib/Target/SparcV9/ModuloScheduling/MSchedGraph.h
lib/Target/SparcV9/ModuloScheduling/ModuloScheduling.cpp
lib/Target/SparcV9/ModuloScheduling/ModuloScheduling.h

index f106722fa8903238df8fa21d07655c6150f5c341..f60d3d5f613373b195200ac228bfdcb2e97647c8 100644 (file)
@@ -141,7 +141,10 @@ void MSchedGraph::deleteNode(MSchedGraphNode *node) {
 //Create a graph for a machine block. The ignoreInstrs map is so that we ignore instructions
 //associated to the index variable since this is a special case in Modulo Scheduling.
 //We only want to deal with the body of the loop.
-MSchedGraph::MSchedGraph(const MachineBasicBlock *bb, const TargetMachine &targ, AliasAnalysis &AA, TargetData &TD, std::map<const MachineInstr*, unsigned> &ignoreInstrs)
+MSchedGraph::MSchedGraph(const MachineBasicBlock *bb, const TargetMachine &targ, AliasAnalysis &AA, 
+                        TargetData &TD, std::map<const MachineInstr*, unsigned> &ignoreInstrs, 
+                        DependenceAnalyzer &DA, std::map<MachineInstr*, Instruction*> &machineTollvm
+                        )
   : BB(bb), Target(targ) {
   
   //Make sure BB is not null, 
@@ -150,7 +153,7 @@ MSchedGraph::MSchedGraph(const MachineBasicBlock *bb, const TargetMachine &targ,
   //DEBUG(std::cerr << "Constructing graph for " << bb << "\n");
 
   //Create nodes and edges for this BB
-  buildNodesAndEdges(AA, TD, ignoreInstrs);
+  buildNodesAndEdges(AA, TD, ignoreInstrs, DA, machineTollvm);
 
   //Experimental!
   //addBranchEdges();
@@ -270,7 +273,10 @@ void MSchedGraph::addBranchEdges() {
 
 
 //Add edges between the nodes
-void MSchedGraph::buildNodesAndEdges(AliasAnalysis &AA, TargetData &TD, std::map<const MachineInstr*, unsigned> &ignoreInstrs) {
+void MSchedGraph::buildNodesAndEdges(AliasAnalysis &AA, TargetData &TD, 
+                                    std::map<const MachineInstr*, unsigned> &ignoreInstrs,
+                                    DependenceAnalyzer &DA,
+                                    std::map<MachineInstr*, Instruction*> &machineTollvm) {
   
   //Get Machine target information for calculating latency
   const TargetInstrInfo *MTI = Target.getInstrInfo();
@@ -405,7 +411,7 @@ void MSchedGraph::buildNodesAndEdges(AliasAnalysis &AA, TargetData &TD, std::map
 
   }
 
-  addMemEdges(memInstructions, AA, TD);
+  addMemEdges(memInstructions, AA, TD, DA, machineTollvm);
   addMachRegEdges(regNumtoNodeMap);
 
   //Finally deal with PHI Nodes and Value*
@@ -584,7 +590,9 @@ void MSchedGraph::addMachRegEdges(std::map<int, std::vector<OpIndexNodePair> >&
 
 //Add edges between all loads and stores
 //Can be less strict with alias analysis and data dependence analysis.
-void MSchedGraph::addMemEdges(const std::vector<MSchedGraphNode*>& memInst, AliasAnalysis &AA, TargetData &TD) {
+void MSchedGraph::addMemEdges(const std::vector<MSchedGraphNode*>& memInst, AliasAnalysis &AA, 
+                             TargetData &TD, DependenceAnalyzer &DA, 
+                             std::map<MachineInstr*, Instruction*> &machineTollvm) {
 
   //Get Target machine instruction info
   const TargetInstrInfo *TMI = Target.getInstrInfo();
@@ -598,11 +606,16 @@ void MSchedGraph::addMemEdges(const std::vector<MSchedGraphNode*>& memInst, Alia
     //Get the machine opCode to determine type of memory instruction
     MachineOpCode srcNodeOpCode = srcInst->getOpcode();
     
-      
     //All instructions after this one in execution order have an iteration delay of 0
     for(unsigned destIndex = srcIndex + 1; destIndex < memInst.size(); ++destIndex) {
   
       MachineInstr *destInst = (MachineInstr*) memInst[destIndex]->getInst();
+      bool malias = false;
+
+      DEBUG(std::cerr << "MInst1: " << *srcInst << "\n");
+      DEBUG(std::cerr << "Inst1: " << *machineTollvm[srcInst] << "\n");
+      DEBUG(std::cerr << "MInst2: " << *destInst << "\n");
+      DEBUG(std::cerr << "Inst2: " << *machineTollvm[destInst] << "\n");
 
       //Add Anti dependencies (store after load)
       //Source is a Load
@@ -613,14 +626,24 @@ void MSchedGraph::addMemEdges(const std::vector<MSchedGraphNode*>& memInst, Alia
 
          //Get the Value* that we are reading from the load, always the first op
          const MachineOperand &mOp = srcInst->getOperand(0);
-         assert((mOp.isUse() && (mOp.getType() == MachineOperand::MO_VirtualRegister)) && "Assumed first operand was a use and a value*\n");
-         
-         //Get the value* for the store
          const MachineOperand &mOp2 = destInst->getOperand(0);
-         assert(mOp2.getType() == MachineOperand::MO_VirtualRegister && "Assumed first operand was a value*\n");
-
+         
+         if(mOp.hasAllocatedReg())
+           if(mOp.getReg() == SparcV9::g0)
+             continue;
+           else
+             malias = true;
+         if(mOp2.hasAllocatedReg())
+           if(mOp2.getReg() == SparcV9::g0)
+             continue;
+           else
+             malias = true;
+
+            //compare to DA
+         DependenceResult dr = DA.getDependenceInfo(machineTollvm[srcInst], machineTollvm[destInst]);
+         
          //Only add the edge if we can't verify that they do not alias
-         if(AA.alias(mOp2.getVRegValue(), 
+         if(malias || AA.alias(mOp2.getVRegValue(), 
                      (unsigned)TD.getTypeSize(mOp2.getVRegValue()->getType()),
                      mOp.getVRegValue(), 
                      (unsigned)TD.getTypeSize(mOp.getVRegValue()->getType()))
@@ -630,23 +653,38 @@ void MSchedGraph::addMemEdges(const std::vector<MSchedGraphNode*>& memInst, Alia
            memInst[srcIndex]->addOutEdge(memInst[destIndex], 
                                          MSchedGraphEdge::MemoryDep, 
                                          MSchedGraphEdge::AntiDep);
+
+           assert(dr.dependences.size() == 1 && "Expected at least one dependence\n");
+
          }
+         else
+           assert(dr.dependences.size() == 0 && "Expected no dependence\n");
        }
       }
        
       //If source is a store, add output and true dependencies
       if(TMI->isStore(srcNodeOpCode)) {
-       
-       //Get the Value* that we are reading from the store (src), always the first op
-       const MachineOperand &mOp = srcInst->getOperand(0);
-       assert(mOp.getType() == MachineOperand::MO_VirtualRegister && "Assumed first operand was a use and a value*\n");
 
        //Get the Value* that we are reading from the load, always the first op
-       const MachineOperand &mOp2 = srcInst->getOperand(0);
-       assert((mOp2.isUse() && (mOp2.getType() == MachineOperand::MO_VirtualRegister)) && "Assumed first operand was a use and a value*\n");
+       const MachineOperand &mOp = srcInst->getOperand(0);
+       const MachineOperand &mOp2 = destInst->getOperand(0);
+       
+       if(mOp.hasAllocatedReg())
+         if(mOp.getReg() == SparcV9::g0)
+           continue;
+         else
+           malias = true;
+       if(mOp2.hasAllocatedReg())
+         if(mOp2.getReg() == SparcV9::g0)
+           continue;
+         else
+           malias = true;
+       
+       //compare to DA
+       DependenceResult dr = DA.getDependenceInfo(machineTollvm[srcInst], machineTollvm[destInst]);
        
        //Only add the edge if we can't verify that they do not alias
-       if(AA.alias(mOp2.getVRegValue(), 
+       if(malias || AA.alias(mOp2.getVRegValue(), 
                    (unsigned)TD.getTypeSize(mOp2.getVRegValue()->getType()),
                    mOp.getVRegValue(), 
                    (unsigned)TD.getTypeSize(mOp.getVRegValue()->getType()))
@@ -660,7 +698,12 @@ void MSchedGraph::addMemEdges(const std::vector<MSchedGraphNode*>& memInst, Alia
            memInst[srcIndex]->addOutEdge(memInst[destIndex], 
                                          MSchedGraphEdge::MemoryDep, 
                                          MSchedGraphEdge::TrueDep);
+         assert(dr.dependences.size() == 1 && "Expected at least one dependence\n");
+
        }
+       
+       else
+         assert(dr.dependences.size() == 0 && "Expected no dependence\n");
       }
     }
     
@@ -668,39 +711,55 @@ void MSchedGraph::addMemEdges(const std::vector<MSchedGraphNode*>& memInst, Alia
     for(unsigned destIndex = 0; destIndex < srcIndex; ++destIndex) {
       
       MachineInstr *destInst = (MachineInstr*) memInst[destIndex]->getInst();
+      bool malias = false;
 
       //source is a Load, so add anti-dependencies (store after load)
       if(TMI->isLoad(srcNodeOpCode)) {
-       //Get the Value* that we are reading from the load, always the first op
-         const MachineOperand &mOp = srcInst->getOperand(0);
-         assert((mOp.isUse() && (mOp.getType() == MachineOperand::MO_VirtualRegister)) && "Assumed first operand was a use and a value*\n");
-         
-         //Get the value* for the store
-         const MachineOperand &mOp2 = destInst->getOperand(0);
-         assert(mOp2.getType() == MachineOperand::MO_VirtualRegister && "Assumed first operand was a value*\n");
 
-         //Only add the edge if we can't verify that they do not alias
-         if(AA.alias(mOp2.getVRegValue(), 
-                     (unsigned)TD.getTypeSize(mOp2.getVRegValue()->getType()),
-                     mOp.getVRegValue(), 
-                     (unsigned)TD.getTypeSize(mOp.getVRegValue()->getType()))
-            != AliasAnalysis::NoAlias) {
-           if(TMI->isStore(memInst[destIndex]->getInst()->getOpcode()))
-             memInst[srcIndex]->addOutEdge(memInst[destIndex], 
-                                           MSchedGraphEdge::MemoryDep, 
-                                           MSchedGraphEdge::AntiDep, 1);
-         }
+       //Get the Value* that we are reading from the load, always the first op
+       const MachineOperand &mOp = srcInst->getOperand(0);
+       const MachineOperand &mOp2 = destInst->getOperand(0);
+       
+       if(mOp.hasAllocatedReg())
+         if(mOp.getReg() == SparcV9::g0)
+           continue;
+         else
+           malias = true;
+       if(mOp2.hasAllocatedReg())
+         if(mOp2.getReg() == SparcV9::g0)
+           continue;
+         else
+           malias = true;
+       
+       //Only add the edge if we can't verify that they do not alias
+       if(AA.alias(mOp2.getVRegValue(), 
+                   (unsigned)TD.getTypeSize(mOp2.getVRegValue()->getType()),
+                   mOp.getVRegValue(), 
+                   (unsigned)TD.getTypeSize(mOp.getVRegValue()->getType()))
+          != AliasAnalysis::NoAlias) {
+         if(TMI->isStore(memInst[destIndex]->getInst()->getOpcode()))
+           memInst[srcIndex]->addOutEdge(memInst[destIndex], 
+                                         MSchedGraphEdge::MemoryDep, 
+                                         MSchedGraphEdge::AntiDep, 1);
+       }
       }
       if(TMI->isStore(srcNodeOpCode)) {
        
-       //Get the Value* that we are reading from the store (src), always the first op
-       const MachineOperand &mOp = srcInst->getOperand(0);
-       assert(mOp.getType() == MachineOperand::MO_VirtualRegister && "Assumed first operand was a use and a value*\n");
-       
        //Get the Value* that we are reading from the load, always the first op
-       const MachineOperand &mOp2 = srcInst->getOperand(0);
-       assert((mOp2.isUse() && (mOp2.getType() == MachineOperand::MO_VirtualRegister)) && "Assumed first operand was a use and a value*\n");
+       const MachineOperand &mOp = srcInst->getOperand(0);
+       const MachineOperand &mOp2 = destInst->getOperand(0);
        
+       if(mOp.hasAllocatedReg())
+         if(mOp.getReg() == SparcV9::g0)
+           continue;
+         else
+           malias = true;
+       if(mOp2.hasAllocatedReg())
+         if(mOp2.getReg() == SparcV9::g0)
+           continue;
+         else
+           malias = true;
+
        //Only add the edge if we can't verify that they do not alias
        if(AA.alias(mOp2.getVRegValue(), 
                    (unsigned)TD.getTypeSize(mOp2.getVRegValue()->getType()),
index ebff43e5900b50cb0cbf4ff4dd13b27f602bf155..bcc78d0df3309e4733e9e4805a6129f621195462 100644 (file)
@@ -16,7 +16,7 @@
 
 #ifndef LLVM_MSCHEDGRAPH_H
 #define LLVM_MSCHEDGRAPH_H
-
+#include "DependenceAnalyzer.h"
 #include "llvm/Analysis/AliasAnalysis.h"
 #include "llvm/CodeGen/MachineInstr.h"
 #include "llvm/Target/TargetMachine.h"
@@ -241,18 +241,20 @@ namespace llvm {
 
     //Add Nodes and Edges to this graph for our BB
     typedef std::pair<int, MSchedGraphNode*> OpIndexNodePair;
-    void buildNodesAndEdges(AliasAnalysis &AA, TargetData &TD, std::map<const MachineInstr*, unsigned> &ignoreInstrs);
+    void buildNodesAndEdges(AliasAnalysis &AA, TargetData &TD, std::map<const MachineInstr*, unsigned> &ignoreInstrs, DependenceAnalyzer &DA, std::map<MachineInstr*, Instruction*> &machineTollvm);
     void addValueEdges(std::vector<OpIndexNodePair> &NodesInMap, 
                       MSchedGraphNode *node,
                       bool nodeIsUse, bool nodeIsDef, std::vector<const MachineInstr*> &phiInstrs, int diff=0);
     void addMachRegEdges(std::map<int, 
                         std::vector<OpIndexNodePair> >& regNumtoNodeMap);
-    void addMemEdges(const std::vector<MSchedGraphNode*>& memInst, AliasAnalysis &AA, TargetData &TD);
+    void addMemEdges(const std::vector<MSchedGraphNode*>& memInst, AliasAnalysis &AA, TargetData &TD,
+                    DependenceAnalyzer &DA, std::map<MachineInstr*, Instruction*> &machineTollvm);
     void addBranchEdges();
 
   public:
-    MSchedGraph(const MachineBasicBlock *bb, const TargetMachine &targ, AliasAnalysis &AA, TargetData &TD,
-               std::map<const MachineInstr*, unsigned> &ignoreInstrs);
+    MSchedGraph(const MachineBasicBlock *bb, const TargetMachine &targ, AliasAnalysis &AA, 
+               TargetData &TD, std::map<const MachineInstr*, unsigned> &ignoreInstrs, 
+               DependenceAnalyzer &DA, std::map<MachineInstr*, Instruction*> &machineTollvm);
 
     //Copy constructor with maps to link old nodes to new nodes
     MSchedGraph(const MSchedGraph &G, std::map<MSchedGraphNode*, MSchedGraphNode*> &newNodes);
index 5441d3cec47c7857b39010c307986a65f3072d42..6adb5f5225dc3c826480cca49400d14b142cf1c6 100644 (file)
@@ -152,6 +152,7 @@ bool ModuloSchedulingPass::runOnFunction(Function &F) {
   //Get MachineFunction
   MachineFunction &MF = MachineFunction::get(&F);
  
+  DependenceAnalyzer &DA = getAnalysis<DependenceAnalyzer>();
   AliasAnalysis &AA = getAnalysis<AliasAnalysis>();
   TargetData &TD = getAnalysis<TargetData>();
 
@@ -191,7 +192,7 @@ bool ModuloSchedulingPass::runOnFunction(Function &F) {
       continue;
     }
 
-    MSchedGraph *MSG = new MSchedGraph(*BI, target, AA, TD, indVarInstrs[*BI]);
+    MSchedGraph *MSG = new MSchedGraph(*BI, target, AA, TD, indVarInstrs[*BI], DA, machineTollvm[*BI]);
     
     //Write Graph out to file
     DEBUG(WriteGraphToFile(std::cerr, F.getName(), MSG));
@@ -349,7 +350,6 @@ bool ModuloSchedulingPass::MachineBBisValid(const MachineBasicBlock *BI) {
   if(BI->getBasicBlock()->size() == 1)
     return false;
 
-
   //Increase number of single basic block loops for stats
   ++SingleBBLoops;
 
@@ -363,8 +363,11 @@ bool ModuloSchedulingPass::MachineBBisValid(const MachineBasicBlock *BI) {
   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))
       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
@@ -422,6 +425,15 @@ bool ModuloSchedulingPass::MachineBBisValid(const MachineBasicBlock *BI) {
          std::cerr << **N << "\n";
        });
 
+  //Create map of machine instr to llvm instr
+  std::map<MachineInstr*, Instruction*> mllvm;
+  for(BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) {
+    MachineCodeForInstruction & tempMvec = MachineCodeForInstruction::get(I);
+    for (unsigned j = 0; j < tempMvec.size(); j++) {
+      mllvm[tempMvec[j]] = I;
+    }
+  }
+
   //Convert list of LLVM Instructions to list of Machine instructions
   std::map<const MachineInstr*, unsigned> mIndVar;
   for(std::set<Instruction*>::iterator N = indVar.begin(), NE = indVar.end(); N != NE; ++N) {
@@ -443,7 +455,7 @@ bool ModuloSchedulingPass::MachineBBisValid(const MachineBasicBlock *BI) {
 
   //Put into a map for future access
   indVarInstrs[BI] = mIndVar;
-
+  machineTollvm[BI] = mllvm;
   return true;
 }
 
@@ -1864,7 +1876,7 @@ void ModuloSchedulingPass::writePrologues(std::vector<MachineBasicBlock *> &prol
   MSchedGraphNode *branch = 0;
   MSchedGraphNode *BAbranch = 0;
 
-  schedule.print(std::cerr);
+  DEBUG(schedule.print(std::cerr));
 
   std::vector<MSchedGraphNode*> branches;
 
index b36c5b2c20a554ce49094ceef6111818eb3e1a38..b2dba19cb21cd176d705c29d0a31cabd64179485 100644 (file)
@@ -17,7 +17,7 @@
 #include "MSSchedule.h"
 #include "llvm/Function.h"
 #include "llvm/Pass.h"
-#include "llvm/Analysis/AliasAnalysis.h"
+#include "DependenceAnalyzer.h"
 #include "llvm/Target/TargetData.h"
 #include <set>
 
@@ -47,6 +47,9 @@ namespace llvm {
     //Map to hold list of instructions associate to the induction var for each BB
     std::map<const MachineBasicBlock*, std::map<const MachineInstr*, unsigned> > indVarInstrs;
 
+    //Map to hold machine to  llvm instrs for each valid BB
+    std::map<const MachineBasicBlock*, std::map<MachineInstr*, Instruction*> > machineTollvm;
+
     //LLVM Instruction we know we can add TmpInstructions to its MCFI
     Instruction *defaultInst;
 
@@ -145,6 +148,7 @@ namespace llvm {
   
     // getAnalysisUsage
     virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+      AU.addRequired<DependenceAnalyzer>();
       AU.addRequired<AliasAnalysis>();
       AU.addRequired<TargetData>();
     }