From 5e9f35234653123de9b7b0bf4deb1012cd7deb63 Mon Sep 17 00:00:00 2001 From: Tanya Lattner Date: Tue, 29 Mar 2005 20:35:10 +0000 Subject: [PATCH] Compare dependence analysis with llvm instructions versus machine instrutions. the problem with using machine instructions and alias analysis is that aa does not handle tmp instructions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@20931 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../SparcV9/ModuloScheduling/MSchedGraph.cpp | 143 +++++++++++++----- .../SparcV9/ModuloScheduling/MSchedGraph.h | 12 +- .../ModuloScheduling/ModuloScheduling.cpp | 20 ++- .../ModuloScheduling/ModuloScheduling.h | 6 +- 4 files changed, 129 insertions(+), 52 deletions(-) diff --git a/lib/Target/SparcV9/ModuloScheduling/MSchedGraph.cpp b/lib/Target/SparcV9/ModuloScheduling/MSchedGraph.cpp index f106722fa89..f60d3d5f613 100644 --- a/lib/Target/SparcV9/ModuloScheduling/MSchedGraph.cpp +++ b/lib/Target/SparcV9/ModuloScheduling/MSchedGraph.cpp @@ -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 &ignoreInstrs) +MSchedGraph::MSchedGraph(const MachineBasicBlock *bb, const TargetMachine &targ, AliasAnalysis &AA, + TargetData &TD, std::map &ignoreInstrs, + DependenceAnalyzer &DA, std::map &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 &ignoreInstrs) { +void MSchedGraph::buildNodesAndEdges(AliasAnalysis &AA, TargetData &TD, + std::map &ignoreInstrs, + DependenceAnalyzer &DA, + std::map &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 >& //Add edges between all loads and stores //Can be less strict with alias analysis and data dependence analysis. -void MSchedGraph::addMemEdges(const std::vector& memInst, AliasAnalysis &AA, TargetData &TD) { +void MSchedGraph::addMemEdges(const std::vector& memInst, AliasAnalysis &AA, + TargetData &TD, DependenceAnalyzer &DA, + std::map &machineTollvm) { //Get Target machine instruction info const TargetInstrInfo *TMI = Target.getInstrInfo(); @@ -598,11 +606,16 @@ void MSchedGraph::addMemEdges(const std::vector& 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& 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& 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& 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& 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()), diff --git a/lib/Target/SparcV9/ModuloScheduling/MSchedGraph.h b/lib/Target/SparcV9/ModuloScheduling/MSchedGraph.h index ebff43e5900..bcc78d0df33 100644 --- a/lib/Target/SparcV9/ModuloScheduling/MSchedGraph.h +++ b/lib/Target/SparcV9/ModuloScheduling/MSchedGraph.h @@ -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 OpIndexNodePair; - void buildNodesAndEdges(AliasAnalysis &AA, TargetData &TD, std::map &ignoreInstrs); + void buildNodesAndEdges(AliasAnalysis &AA, TargetData &TD, std::map &ignoreInstrs, DependenceAnalyzer &DA, std::map &machineTollvm); void addValueEdges(std::vector &NodesInMap, MSchedGraphNode *node, bool nodeIsUse, bool nodeIsDef, std::vector &phiInstrs, int diff=0); void addMachRegEdges(std::map >& regNumtoNodeMap); - void addMemEdges(const std::vector& memInst, AliasAnalysis &AA, TargetData &TD); + void addMemEdges(const std::vector& memInst, AliasAnalysis &AA, TargetData &TD, + DependenceAnalyzer &DA, std::map &machineTollvm); void addBranchEdges(); public: - MSchedGraph(const MachineBasicBlock *bb, const TargetMachine &targ, AliasAnalysis &AA, TargetData &TD, - std::map &ignoreInstrs); + MSchedGraph(const MachineBasicBlock *bb, const TargetMachine &targ, AliasAnalysis &AA, + TargetData &TD, std::map &ignoreInstrs, + DependenceAnalyzer &DA, std::map &machineTollvm); //Copy constructor with maps to link old nodes to new nodes MSchedGraph(const MSchedGraph &G, std::map &newNodes); diff --git a/lib/Target/SparcV9/ModuloScheduling/ModuloScheduling.cpp b/lib/Target/SparcV9/ModuloScheduling/ModuloScheduling.cpp index 5441d3cec47..6adb5f5225d 100644 --- a/lib/Target/SparcV9/ModuloScheduling/ModuloScheduling.cpp +++ b/lib/Target/SparcV9/ModuloScheduling/ModuloScheduling.cpp @@ -152,6 +152,7 @@ bool ModuloSchedulingPass::runOnFunction(Function &F) { //Get MachineFunction MachineFunction &MF = MachineFunction::get(&F); + DependenceAnalyzer &DA = getAnalysis(); AliasAnalysis &AA = getAnalysis(); TargetData &TD = getAnalysis(); @@ -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 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 mIndVar; for(std::set::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 &prol MSchedGraphNode *branch = 0; MSchedGraphNode *BAbranch = 0; - schedule.print(std::cerr); + DEBUG(schedule.print(std::cerr)); std::vector branches; diff --git a/lib/Target/SparcV9/ModuloScheduling/ModuloScheduling.h b/lib/Target/SparcV9/ModuloScheduling/ModuloScheduling.h index b36c5b2c20a..b2dba19cb21 100644 --- a/lib/Target/SparcV9/ModuloScheduling/ModuloScheduling.h +++ b/lib/Target/SparcV9/ModuloScheduling/ModuloScheduling.h @@ -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 @@ -47,6 +47,9 @@ namespace llvm { //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; @@ -145,6 +148,7 @@ namespace llvm { // getAnalysisUsage virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequired(); AU.addRequired(); AU.addRequired(); }