mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-25 21:46:50 +00:00
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
This commit is contained in:
parent
5ec3a63f6d
commit
5e9f352346
@ -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()),
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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>();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user