aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVikram S. Adve <vadve@cs.uiuc.edu>2001-11-08 05:20:23 +0000
committerVikram S. Adve <vadve@cs.uiuc.edu>2001-11-08 05:20:23 +0000
commite64574ce7198dc0967caf811dd295fd8df91409c (patch)
tree35934889e033953fbd0fc522d42565e4b764b353
parentaf1d2c80e03b01e995e7a5cdbcdd625082a4ebfb (diff)
Major change to how defs are found when adding dependences (they
are now found as part of the initial walk of the machine code). Also memory load/store instructions can be generated for non-memory LLVM instructions, which wasn't handled before. It is now. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@1199 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/CodeGen/InstrSched/SchedGraph.cpp222
-rw-r--r--lib/CodeGen/InstrSched/SchedGraph.h18
-rw-r--r--lib/Target/SparcV9/InstrSched/SchedGraph.cpp222
-rw-r--r--lib/Target/SparcV9/InstrSched/SchedGraph.h18
4 files changed, 138 insertions, 342 deletions
diff --git a/lib/CodeGen/InstrSched/SchedGraph.cpp b/lib/CodeGen/InstrSched/SchedGraph.cpp
index c19515ed05..60913123ac 100644
--- a/lib/CodeGen/InstrSched/SchedGraph.cpp
+++ b/lib/CodeGen/InstrSched/SchedGraph.cpp
@@ -446,98 +446,64 @@ static const unsigned int SG_DepOrderArray[][3] = {
};
+// Add a dependence edge between every pair of machine load/store/call
+// instructions, where at least one is a store or a call.
+// Use latency 1 just to ensure that memory operations are ordered;
+// latency does not otherwise matter (true dependences enforce that).
+//
void
-SchedGraph::addMemEdges(const vector<const Instruction*>& memVec,
+SchedGraph::addMemEdges(const vector<SchedGraphNode*>& memNodeVec,
const TargetMachine& target)
{
const MachineInstrInfo& mii = target.getInstrInfo();
- for (unsigned im=0, NM=memVec.size(); im < NM; im++)
+ // Instructions in memNodeVec are in execution order within the basic block,
+ // so simply look at all pairs <memNodeVec[i], memNodeVec[j: j > i]>.
+ //
+ for (unsigned im=0, NM=memNodeVec.size(); im < NM; im++)
{
- const Instruction* fromInstr = memVec[im];
- int fromType = (fromInstr->getOpcode() == Instruction::Call
- ? SG_CALL_REF
- : (fromInstr->getOpcode() == Instruction::Load
- ? SG_LOAD_REF
- : SG_STORE_REF));
-
+ MachineOpCode fromOpCode = memNodeVec[im]->getOpCode();
+ int fromType = mii.isCall(fromOpCode)? SG_CALL_REF
+ : mii.isLoad(fromOpCode)? SG_LOAD_REF
+ : SG_STORE_REF;
for (unsigned jm=im+1; jm < NM; jm++)
{
- const Instruction* toInstr = memVec[jm];
- int toType = (fromInstr->getOpcode() == Instruction::Call? 2
- : ((fromInstr->getOpcode()==Instruction::Load)? 0:1));
-
- if (fromType == SG_LOAD_REF && toType == SG_LOAD_REF)
- continue;
+ MachineOpCode toOpCode = memNodeVec[jm]->getOpCode();
+ int toType = mii.isCall(toOpCode)? SG_CALL_REF
+ : mii.isLoad(toOpCode)? SG_LOAD_REF
+ : SG_STORE_REF;
- unsigned int depOrderType = SG_DepOrderArray[fromType][toType];
-
- MachineCodeForVMInstr& fromInstrMvec=fromInstr->getMachineInstrVec();
- MachineCodeForVMInstr& toInstrMvec = toInstr->getMachineInstrVec();
-
- // We have two VM memory instructions, and at least one is a store
- // or a call. Add edges between all machine load/store/call instrs.
- // Use a latency of 1 to ensure that memory operations are ordered;
- // latency does not otherwise matter (true dependences enforce that).
- //
- for (unsigned i=0, N=fromInstrMvec.size(); i < N; i++)
- {
- MachineOpCode fromOpCode = fromInstrMvec[i]->getOpCode();
-
- if (mii.isLoad(fromOpCode) || mii.isStore(fromOpCode) ||
- mii.isCall(fromOpCode))
- {
- SchedGraphNode* fromNode =
- this->getGraphNodeForInstr(fromInstrMvec[i]);
- assert(fromNode && "No node for memory instr?");
-
- for (unsigned j=0, M=toInstrMvec.size(); j < M; j++)
- {
- MachineOpCode toOpCode = toInstrMvec[j]->getOpCode();
- if (mii.isLoad(toOpCode) || mii.isStore(toOpCode)
- || mii.isCall(fromOpCode))
- {
- SchedGraphNode* toNode =
- this->getGraphNodeForInstr(toInstrMvec[j]);
- assert(toNode && "No node for memory instr?");
-
- (void) new SchedGraphEdge(fromNode, toNode,
- SchedGraphEdge::MemoryDep,
- depOrderType, 1);
- }
- }
- }
- }
- }
+ if (fromType != SG_LOAD_REF || toType != SG_LOAD_REF)
+ (void) new SchedGraphEdge(memNodeVec[im], memNodeVec[jm],
+ SchedGraphEdge::MemoryDep,
+ SG_DepOrderArray[fromType][toType], 1);
+ }
}
-}
-
+}
+// Add edges from/to CC reg instrs to/from call instrs.
+// Essentially this prevents anything that sets or uses a CC reg from being
+// reordered w.r.t. a call.
+// Use a latency of 0 because we only need to prevent out-of-order issue,
+// like with control dependences.
+//
void
-SchedGraph::addCallCCEdges(const vector<const Instruction*>& memVec,
+SchedGraph::addCallCCEdges(const vector<SchedGraphNode*>& memNodeVec,
MachineCodeForBasicBlock& bbMvec,
const TargetMachine& target)
{
const MachineInstrInfo& mii = target.getInstrInfo();
vector<SchedGraphNode*> callNodeVec;
- // Find the call machine instructions and put them in a vector.
- // By using memVec, we avoid searching the entire machine code of the BB.
- //
- for (unsigned im=0, NM=memVec.size(); im < NM; im++)
- if (memVec[im]->getOpcode() == Instruction::Call)
- {
- MachineCodeForVMInstr& callMvec=memVec[im]->getMachineInstrVec();
- for (unsigned i=0; i < callMvec.size(); ++i)
- if (mii.isCall(callMvec[i]->getOpCode()))
- callNodeVec.push_back(this->getGraphNodeForInstr(callMvec[i]));
- }
+ // Find the call instruction nodes and put them in a vector.
+ for (unsigned im=0, NM=memNodeVec.size(); im < NM; im++)
+ if (mii.isCall(memNodeVec[im]->getOpCode()))
+ callNodeVec.push_back(memNodeVec[im]);
- // Now add additional edges from/to CC reg instrs to/from call instrs.
- // Essentially this prevents anything that sets or uses a CC reg from being
- // reordered w.r.t. a call.
- // Use a latency of 0 because we only need to prevent out-of-order issue,
- // like with control dependences.
+ // Now walk the entire basic block, looking for CC instructions *and*
+ // call instructions, and keep track of the order of the instructions.
+ // Use the call node vec to quickly find earlier and later call nodes
+ // relative to the current CC instruction.
//
int lastCallNodeIdx = -1;
for (unsigned i=0, N=bbMvec.size(); i < N; i++)
@@ -610,81 +576,6 @@ SchedGraph::addMachineRegEdges(RegToRefVecMap& regToRefVecMap,
}
}
-#undef OLD_SSA_EDGE_CONSTRUCTION
-#ifdef OLD_SSA_EDGE_CONSTRUCTION
-//
-// Delete this code once a few more tests pass.
-//
-inline void
-CreateSSAEdge(SchedGraph* graph,
- MachineInstr* defInstr,
- SchedGraphNode* node,
- const Value* val)
-{
- // this instruction does define value `val'.
- // if there is a node for it in the same graph, add an edge.
- SchedGraphNode* defNode = graph->getGraphNodeForInstr(defInstr);
- if (defNode != NULL && defNode != node)
- (void) new SchedGraphEdge(defNode, node, val);
-}
-
-
-void
-SchedGraph::addSSAEdge(SchedGraphNode* destNode,
- const Instruction* defVMInstr,
- const Value* defValue,
- const TargetMachine& target)
-{
- // Phi instructions are the only ones that produce a value but don't get
- // any non-dummy machine instructions. Return here as an optimization.
- //
- if (isa<PHINode>(defVMInstr))
- return;
-
- // Now add the graph edge for the appropriate machine instruction(s).
- // Note that multiple machine instructions generated for the
- // def VM instruction may modify the register for the def value.
- //
- MachineCodeForVMInstr& defMvec = defVMInstr->getMachineInstrVec();
- const MachineInstrInfo& mii = target.getInstrInfo();
-
- for (unsigned i=0, N=defMvec.size(); i < N; i++)
- {
- bool edgeAddedForInstr = false;
-
- // First check the explicit operands
- for (int o=0, N=mii.getNumOperands(defMvec[i]->getOpCode()); o < N; o++)
- {
- const MachineOperand& defOp = defMvec[i]->getOperand(o);
-
- if (defOp.opIsDef()
- && (defOp.getOperandType() == MachineOperand::MO_VirtualRegister
- || defOp.getOperandType() == MachineOperand::MO_CCRegister)
- && (defOp.getVRegValue() == defValue))
- {
- CreateSSAEdge(this, defMvec[i], destNode, defValue);
- edgeAddedForInstr = true;
- break;
- }
- }
-
- // Then check the implicit operands
- if (! edgeAddedForInstr)
- {
- for (unsigned o=0, N=defMvec[i]->getNumImplicitRefs(); o < N; ++o)
- if (defMvec[i]->implicitRefIsDefined(o) &&
- defMvec[i]->getImplicitRef(o) == defValue)
- {
- CreateSSAEdge(this, defMvec[i], destNode, defValue);
- edgeAddedForInstr = true;
- break;
- }
- }
- }
-}
-
-#endif OLD_SSA_EDGE_CONSTRUCTION
-
void
SchedGraph::addSSAEdge(SchedGraphNode* destNode,
@@ -817,11 +708,17 @@ SchedGraph::addNonSSAEdgesForValue(const Instruction* instr,
void
SchedGraph::findDefUseInfoAtInstr(const TargetMachine& target,
SchedGraphNode* node,
+ vector<SchedGraphNode*>& memNodeVec,
RegToRefVecMap& regToRefVecMap,
ValueToDefVecMap& valueToDefVecMap)
{
const MachineInstrInfo& mii = target.getInstrInfo();
+
+ MachineOpCode opCode = node->getOpCode();
+ if (mii.isLoad(opCode) || mii.isStore(opCode) || mii.isCall(opCode))
+ memNodeVec.push_back(node);
+
// Collect the register references and value defs. for explicit operands
//
const MachineInstr& minstr = * node->getMachineInstr();
@@ -835,7 +732,8 @@ SchedGraph::findDefUseInfoAtInstr(const TargetMachine& target,
{
int regNum = mop.getMachineRegNum();
if (regNum != target.getRegInfo().getZeroRegNum())
- regToRefVecMap[mop.getMachineRegNum()].push_back(make_pair(node, i));
+ regToRefVecMap[mop.getMachineRegNum()].push_back(make_pair(node,
+ i));
continue; // nothing more to do
}
@@ -851,7 +749,7 @@ SchedGraph::findDefUseInfoAtInstr(const TargetMachine& target,
const Instruction* defInstr = cast<Instruction>(mop.getVRegValue());
valueToDefVecMap[defInstr].push_back(make_pair(node, i));
}
-
+
//
// Collect value defs. for implicit operands. The interface to extract
// them assumes they must be virtual registers!
@@ -869,7 +767,7 @@ SchedGraph::findDefUseInfoAtInstr(const TargetMachine& target,
void
SchedGraph::buildNodesforVMInstr(const TargetMachine& target,
const Instruction* instr,
- vector<const Instruction*>& memVec,
+ vector<SchedGraphNode*>& memNodeVec,
RegToRefVecMap& regToRefVecMap,
ValueToDefVecMap& valueToDefVecMap)
{
@@ -881,16 +779,11 @@ SchedGraph::buildNodesforVMInstr(const TargetMachine& target,
SchedGraphNode* node = new SchedGraphNode(getNumNodes(),
instr, mvec[i], target);
this->noteGraphNodeForInstr(mvec[i], node);
-
+
// Remember all register references and value defs
- findDefUseInfoAtInstr(target, node, regToRefVecMap, valueToDefVecMap);
+ findDefUseInfoAtInstr(target, node,
+ memNodeVec, regToRefVecMap, valueToDefVecMap);
}
-
- // Remember load/store/call instructions to add memory deps later.
- if (instr->getOpcode() == Instruction::Load ||
- instr->getOpcode() == Instruction::Store ||
- instr->getOpcode() == Instruction::Call)
- memVec.push_back(instr);
}
@@ -908,10 +801,11 @@ SchedGraph::buildGraph(const TargetMachine& target)
// each Value.
ValueToDefVecMap valueToDefVecMap;
- // Use this data structure to note all LLVM memory instructions.
+ // Use this data structure to note all memory instructions.
// We use this to add memory dependence edges without a second full walk.
//
- vector<const Instruction*> memVec;
+ // vector<const Instruction*> memVec;
+ vector<SchedGraphNode*> memNodeVec;
// Use this data structure to note any uses or definitions of
// machine registers so we can add edges for those later without
@@ -941,7 +835,7 @@ SchedGraph::buildGraph(const TargetMachine& target)
// Build graph nodes for this VM instruction and gather def/use info.
// Do these together in a single pass over all machine instructions.
buildNodesforVMInstr(target, instr,
- memVec, regToRefVecMap, valueToDefVecMap);
+ memNodeVec, regToRefVecMap, valueToDefVecMap);
}
//----------------------------------------------------------------
@@ -967,10 +861,10 @@ SchedGraph::buildGraph(const TargetMachine& target)
// Then add memory dep edges: store->load, load->store, and store->store.
// Call instructions are treated as both load and store.
- this->addMemEdges(memVec, target);
+ this->addMemEdges(memNodeVec, target);
// Then add edges between call instructions and CC set/use instructions
- this->addCallCCEdges(memVec, bbMvec, target);
+ this->addCallCCEdges(memNodeVec, bbMvec, target);
// Then add incoming def-use (SSA) edges for each machine instruction.
for (unsigned i=0, N=bbMvec.size(); i < N; i++)
diff --git a/lib/CodeGen/InstrSched/SchedGraph.h b/lib/CodeGen/InstrSched/SchedGraph.h
index ecb72b6c33..6f6739b39b 100644
--- a/lib/CodeGen/InstrSched/SchedGraph.h
+++ b/lib/CodeGen/InstrSched/SchedGraph.h
@@ -22,6 +22,8 @@
#include "llvm/Support/NonCopyable.h"
#include "llvm/Support/HashExtras.h"
#include "llvm/Support/GraphTraits.h"
+#include "llvm/Target/MachineInstrInfo.h"
+#include "llvm/CodeGen/MachineInstr.h"
#include <hash_map>
class Value;
@@ -159,6 +161,7 @@ public:
unsigned int getNodeId () const { return nodeId; }
const Instruction* getInstr () const { return instr; }
const MachineInstr* getMachineInstr () const { return minstr; }
+ const MachineOpCode getOpCode () const { return minstr->getOpCode();}
int getLatency () const { return latency; }
unsigned int getNumInEdges () const { return inEdges.size(); }
unsigned int getNumOutEdges () const { return outEdges.size(); }
@@ -302,28 +305,29 @@ private:
void buildNodesforVMInstr (const TargetMachine& target,
const Instruction* instr,
- vector<const Instruction*>& memVec,
+ vector<SchedGraphNode*>& memNodeVec,
RegToRefVecMap& regToRefVecMap,
ValueToDefVecMap& valueToDefVecMap);
void findDefUseInfoAtInstr (const TargetMachine& target,
SchedGraphNode* node,
+ vector<SchedGraphNode*>& memNodeVec,
RegToRefVecMap& regToRefVecMap,
ValueToDefVecMap& valueToDefVecMap);
- void addEdgesForInstruction (const MachineInstr& minstr,
+ void addEdgesForInstruction(const MachineInstr& minstr,
const ValueToDefVecMap& valueToDefVecMap,
const TargetMachine& target);
void addCDEdges (const TerminatorInst* term,
const TargetMachine& target);
- void addMemEdges (const vector<const Instruction*>& memVec,
- const TargetMachine& target);
+ void addMemEdges (const vector<SchedGraphNode*>& memNodeVec,
+ const TargetMachine& target);
- void addCallCCEdges (const vector<const Instruction*>& memVec,
- MachineCodeForBasicBlock& bbMvec,
- const TargetMachine& target);
+ void addCallCCEdges (const vector<SchedGraphNode*>& memNodeVec,
+ MachineCodeForBasicBlock& bbMvec,
+ const TargetMachine& target);
void addMachineRegEdges (RegToRefVecMap& regToRefVecMap,
const TargetMachine& target);
diff --git a/lib/Target/SparcV9/InstrSched/SchedGraph.cpp b/lib/Target/SparcV9/InstrSched/SchedGraph.cpp
index c19515ed05..60913123ac 100644
--- a/lib/Target/SparcV9/InstrSched/SchedGraph.cpp
+++ b/lib/Target/SparcV9/InstrSched/SchedGraph.cpp
@@ -446,98 +446,64 @@ static const unsigned int SG_DepOrderArray[][3] = {
};
+// Add a dependence edge between every pair of machine load/store/call
+// instructions, where at least one is a store or a call.
+// Use latency 1 just to ensure that memory operations are ordered;
+// latency does not otherwise matter (true dependences enforce that).
+//
void
-SchedGraph::addMemEdges(const vector<const Instruction*>& memVec,
+SchedGraph::addMemEdges(const vector<SchedGraphNode*>& memNodeVec,
const TargetMachine& target)
{
const MachineInstrInfo& mii = target.getInstrInfo();
- for (unsigned im=0, NM=memVec.size(); im < NM; im++)
+ // Instructions in memNodeVec are in execution order within the basic block,
+ // so simply look at all pairs <memNodeVec[i], memNodeVec[j: j > i]>.
+ //
+ for (unsigned im=0, NM=memNodeVec.size(); im < NM; im++)
{
- const Instruction* fromInstr = memVec[im];
- int fromType = (fromInstr->getOpcode() == Instruction::Call
- ? SG_CALL_REF
- : (fromInstr->getOpcode() == Instruction::Load
- ? SG_LOAD_REF
- : SG_STORE_REF));
-
+ MachineOpCode fromOpCode = memNodeVec[im]->getOpCode();
+ int fromType = mii.isCall(fromOpCode)? SG_CALL_REF
+ : mii.isLoad(fromOpCode)? SG_LOAD_REF
+ : SG_STORE_REF;
for (unsigned jm=im+1; jm < NM; jm++)
{
- const Instruction* toInstr = memVec[jm];
- int toType = (fromInstr->getOpcode() == Instruction::Call? 2
- : ((fromInstr->getOpcode()==Instruction::Load)? 0:1));
-
- if (fromType == SG_LOAD_REF && toType == SG_LOAD_REF)
- continue;
+ MachineOpCode toOpCode = memNodeVec[jm]->getOpCode();
+ int toType = mii.isCall(toOpCode)? SG_CALL_REF
+ : mii.isLoad(toOpCode)? SG_LOAD_REF
+ : SG_STORE_REF;
- unsigned int depOrderType = SG_DepOrderArray[fromType][toType];
-
- MachineCodeForVMInstr& fromInstrMvec=fromInstr->getMachineInstrVec();
- MachineCodeForVMInstr& toInstrMvec = toInstr->getMachineInstrVec();
-
- // We have two VM memory instructions, and at least one is a store
- // or a call. Add edges between all machine load/store/call instrs.
- // Use a latency of 1 to ensure that memory operations are ordered;
- // latency does not otherwise matter (true dependences enforce that).
- //
- for (unsigned i=0, N=fromInstrMvec.size(); i < N; i++)
- {
- MachineOpCode fromOpCode = fromInstrMvec[i]->getOpCode();
-
- if (mii.isLoad(fromOpCode) || mii.isStore(fromOpCode) ||
- mii.isCall(fromOpCode))
- {
- SchedGraphNode* fromNode =
- this->getGraphNodeForInstr(fromInstrMvec[i]);
- assert(fromNode && "No node for memory instr?");
-
- for (unsigned j=0, M=toInstrMvec.size(); j < M; j++)
- {
- MachineOpCode toOpCode = toInstrMvec[j]->getOpCode();
- if (mii.isLoad(toOpCode) || mii.isStore(toOpCode)
- || mii.isCall(fromOpCode))
- {
- SchedGraphNode* toNode =
- this->getGraphNodeForInstr(toInstrMvec[j]);
- assert(toNode && "No node for memory instr?");
-
- (void) new SchedGraphEdge(fromNode, toNode,
- SchedGraphEdge::MemoryDep,
- depOrderType, 1);
- }
- }
- }
- }
- }
+ if (fromType != SG_LOAD_REF || toType != SG_LOAD_REF)
+ (void) new SchedGraphEdge(memNodeVec[im], memNodeVec[jm],
+ SchedGraphEdge::MemoryDep,
+ SG_DepOrderArray[fromType][toType], 1);
+ }
}
-}
-
+}
+// Add edges from/to CC reg instrs to/from call instrs.
+// Essentially this prevents anything that sets or uses a CC reg from being
+// reordered w.r.t. a call.
+// Use a latency of 0 because we only need to prevent out-of-order issue,
+// like with control dependences.
+//
void
-SchedGraph::addCallCCEdges(const vector<const Instruction*>& memVec,
+SchedGraph::addCallCCEdges(const vector<SchedGraphNode*>& memNodeVec,
MachineCodeForBasicBlock& bbMvec,
const TargetMachine& target)
{
const MachineInstrInfo& mii = target.getInstrInfo();
vector<SchedGraphNode*> callNodeVec;
- // Find the call machine instructions and put them in a vector.
- // By using memVec, we avoid searching the entire machine code of the BB.
- //
- for (unsigned im=0, NM=memVec.size(); im < NM; im++)
- if (memVec[im]->getOpcode() == Instruction::Call)
- {
- MachineCodeForVMInstr& callMvec=memVec[im]->getMachineInstrVec();
- for (unsigned i=0; i < callMvec.size(); ++i)
- if (mii.isCall(callMvec[i]->getOpCode()))
- callNodeVec.push_back(this->getGraphNodeForInstr(callMvec[i]));
- }
+ // Find the call instruction nodes and put them in a vector.
+ for (unsigned im=0, NM=memNodeVec.size(); im < NM; im++)
+ if (mii.isCall(memNodeVec[im]->getOpCode()))
+ callNodeVec.push_back(memNodeVec[im]);
- // Now add additional edges from/to CC reg instrs to/from call instrs.
- // Essentially this prevents anything that sets or uses a CC reg from being
- // reordered w.r.t. a call.
- // Use a latency of 0 because we only need to prevent out-of-order issue,
- // like with control dependences.
+ // Now walk the entire basic block, looking for CC instructions *and*
+ // call instructions, and keep track of the order of the instructions.
+ // Use the call node vec to quickly find earlier and later call nodes
+ // relative to the current CC instruction.
//
int lastCallNodeIdx = -1;
for (unsigned i=0, N=bbMvec.size(); i < N; i++)
@@ -610,81 +576,6 @@ SchedGraph::addMachineRegEdges(RegToRefVecMap& regToRefVecMap,
}
}
-#undef OLD_SSA_EDGE_CONSTRUCTION
-#ifdef OLD_SSA_EDGE_CONSTRUCTION
-//
-// Delete this code once a few more tests pass.
-//
-inline void
-CreateSSAEdge(SchedGraph* graph,
- MachineInstr* defInstr,
- SchedGraphNode* node,
- const Value* val)
-{
- // this instruction does define value `val'.
- // if there is a node for it in the same graph, add an edge.
- SchedGraphNode* defNode = graph->getGraphNodeForInstr(defInstr);
- if (defNode != NULL && defNode != node)
- (void) new SchedGraphEdge(defNode, node, val);
-}
-
-
-void
-SchedGraph::addSSAEdge(SchedGraphNode* destNode,
- const Instruction* defVMInstr,
- const Value* defValue,
- const TargetMachine& target)
-{
- // Phi instructions are the only ones that produce a value but don't get
- // any non-dummy machine instructions. Return here as an optimization.
- //
- if (isa<PHINode>(defVMInstr))
- return;
-
- // Now add the graph edge for the appropriate machine instruction(s).
- // Note that multiple machine instructions generated for the
- // def VM instruction may modify the register for the def value.
- //
- MachineCodeForVMInstr& defMvec = defVMInstr->getMachineInstrVec();
- const MachineInstrInfo& mii = target.getInstrInfo();
-
- for (unsigned i=0, N=defMvec.size(); i < N; i++)
- {
- bool edgeAddedForInstr = false;
-
- // First check the explicit operands
- for (int o=0, N=mii.getNumOperands(defMvec[i]->getOpCode()); o < N; o++)
- {
- const MachineOperand& defOp = defMvec[i]->getOperand(o);
-
- if (defOp.opIsDef()
- && (defOp.getOperandType() == MachineOperand::MO_VirtualRegister
- || defOp.getOperandType() == MachineOperand::MO_CCRegister)
- && (defOp.getVRegValue() == defValue))
- {
- CreateSSAEdge(this, defMvec[i], destNode, defValue);
- edgeAddedForInstr = true;
- break;
- }
- }
-
- // Then check the implicit operands
- if (! edgeAddedForInstr)
- {
- for (unsigned o=0, N=defMvec[i]->getNumImplicitRefs(); o < N; ++o)
- if (defMvec[i]->implicitRefIsDefined(o) &&
- defMvec[i]->getImplicitRef(o) == defValue)
- {
- CreateSSAEdge(this, defMvec[i], destNode, defValue);
- edgeAddedForInstr = true;
- break;
- }
- }
- }
-}
-
-#endif OLD_SSA_EDGE_CONSTRUCTION
-
void
SchedGraph::addSSAEdge(SchedGraphNode* destNode,
@@ -817,11 +708,17 @@ SchedGraph::addNonSSAEdgesForValue(const Instruction* instr,
void
SchedGraph::findDefUseInfoAtInstr(const TargetMachine& target,
SchedGraphNode* node,
+ vector<SchedGraphNode*>& memNodeVec,
RegToRefVecMap& regToRefVecMap,
ValueToDefVecMap& valueToDefVecMap)
{
const MachineInstrInfo& mii = target.getInstrInfo();
+
+ MachineOpCode opCode = node->getOpCode();
+ if (mii.isLoad(opCode) || mii.isStore(opCode) || mii.isCall(opCode))
+ memNodeVec.push_back(node);
+
// Collect the register references and value defs. for explicit operands
//
const MachineInstr& minstr = * node->getMachineInstr();
@@ -835,7 +732,8 @@ SchedGraph::findDefUseInfoAtInstr(const TargetMachine& target,
{
int regNum = mop.getMachineRegNum();
if (regNum != target.getRegInfo().getZeroRegNum())
- regToRefVecMap[mop.getMachineRegNum()].push_back(make_pair(node, i));
+ regToRefVecMap[mop.getMachineRegNum()].push_back(make_pair(node,
+ i));
continue; // nothing more to do
}
@@ -851,7 +749,7 @@ SchedGraph::findDefUseInfoAtInstr(const TargetMachine& target,
const Instruction* defInstr = cast<Instruction>(mop.getVRegValue());
valueToDefVecMap[defInstr].push_back(make_pair(node, i));
}
-
+
//
// Collect value defs. for implicit operands. The interface to extract
// them assumes they must be virtual registers!
@@ -869,7 +767,7 @@ SchedGraph::findDefUseInfoAtInstr(const TargetMachine& target,
void
SchedGraph::buildNodesforVMInstr(const TargetMachine& target,
const Instruction* instr,
- vector<const Instruction*>& memVec,
+ vector<SchedGraphNode*>& memNodeVec,
RegToRefVecMap& regToRefVecMap,
ValueToDefVecMap& valueToDefVecMap)
{
@@ -881,16 +779,11 @@ SchedGraph::buildNodesforVMInstr(const TargetMachine& target,
SchedGraphNode* node = new SchedGraphNode(getNumNodes(),
instr, mvec[i], target);
this->noteGraphNodeForInstr(mvec[i], node);
-
+
// Remember all register references and value defs
- findDefUseInfoAtInstr(target, node, regToRefVecMap, valueToDefVecMap);
+ findDefUseInfoAtInstr(target, node,
+ memNodeVec, regToRefVecMap, valueToDefVecMap);
}
-
- // Remember load/store/call instructions to add memory deps later.
- if (instr->getOpcode() == Instruction::Load ||
- instr->getOpcode() == Instruction::Store ||
- instr->getOpcode() == Instruction::Call)
- memVec.push_back(instr);
}
@@ -908,10 +801,11 @@ SchedGraph::buildGraph(const TargetMachine& target)
// each Value.
ValueToDefVecMap valueToDefVecMap;
- // Use this data structure to note all LLVM memory instructions.
+ // Use this data structure to note all memory instructions.
// We use this to add memory dependence edges without a second full walk.
//
- vector<const Instruction*> memVec;
+ // vector<const Instruction*> memVec;
+ vector<SchedGraphNode*> memNodeVec;
// Use this data structure to note any uses or definitions of
// machine registers so we can add edges for those later without
@@ -941,7 +835,7 @@ SchedGraph::buildGraph(const TargetMachine& target)
// Build graph nodes for this VM instruction and gather def/use info.
// Do these together in a single pass over all machine instructions.
buildNodesforVMInstr(target, instr,
- memVec, regToRefVecMap, valueToDefVecMap);
+ memNodeVec, regToRefVecMap, valueToDefVecMap);
}
//----------------------------------------------------------------
@@ -967,10 +861,10 @@ SchedGraph::buildGraph(const TargetMachine& target)
// Then add memory dep edges: store->load, load->store, and store->store.
// Call instructions are treated as both load and store.
- this->addMemEdges(memVec, target);
+ this->addMemEdges(memNodeVec, target);
// Then add edges between call instructions and CC set/use instructions
- this->addCallCCEdges(memVec, bbMvec, target);
+ this->addCallCCEdges(memNodeVec, bbMvec, target);
// Then add incoming def-use (SSA) edges for each machine instruction.
for (unsigned i=0, N=bbMvec.size(); i < N; i++)
diff --git a/lib/Target/SparcV9/InstrSched/SchedGraph.h b/lib/Target/SparcV9/InstrSched/SchedGraph.h
index ecb72b6c33..6f6739b39b 100644
--- a/lib/Target/SparcV9/InstrSched/SchedGraph.h
+++ b/lib/Target/SparcV9/InstrSched/SchedGraph.h
@@ -22,6 +22,8 @@
#include "llvm/Support/NonCopyable.h"
#include "llvm/Support/HashExtras.h"
#include "llvm/Support/GraphTraits.h"
+#include "llvm/Target/MachineInstrInfo.h"
+#include "llvm/CodeGen/MachineInstr.h"
#include <hash_map>
class Value;
@@ -159,6 +161,7 @@ public:
unsigned int getNodeId () const { return nodeId; }
const Instruction* getInstr () const { return instr; }
const MachineInstr* getMachineInstr () const { return minstr; }
+ const MachineOpCode getOpCode () const { return minstr->getOpCode();}
int getLatency () const { return latency; }
unsigned int getNumInEdges () const { return inEdges.size(); }
unsigned int getNumOutEdges () const { return outEdges.size(); }
@@ -302,28 +305,29 @@ private:
void buildNodesforVMInstr (const TargetMachine& target,
const Instruction* instr,
- vector<const Instruction*>& memVec,
+ vector<SchedGraphNode*>& memNodeVec,
RegToRefVecMap& regToRefVecMap,
ValueToDefVecMap& valueToDefVecMap);
void findDefUseInfoAtInstr (const TargetMachine& target,
SchedGraphNode* node,
+ vector<SchedGraphNode*>& memNodeVec,
RegToRefVecMap& regToRefVecMap,
ValueToDefVecMap& valueToDefVecMap);
- void addEdgesForInstruction (const MachineInstr& minstr,
+ void addEdgesForInstruction(const MachineInstr& minstr,
const ValueToDefVecMap& valueToDefVecMap,
const TargetMachine& target);
void addCDEdges (const TerminatorInst* term,
const TargetMachine& target);
- void addMemEdges (const vector<const Instruction*>& memVec,
- const TargetMachine& target);
+ void addMemEdges (const vector<SchedGraphNode*>& memNodeVec,
+ const TargetMachine& target);
- void addCallCCEdges (const vector<const Instruction*>& memVec,
- MachineCodeForBasicBlock& bbMvec,
- const TargetMachine& target);
+ void addCallCCEdges (const vector<SchedGraphNode*>& memNodeVec,
+ MachineCodeForBasicBlock& bbMvec,
+ const TargetMachine& target);
void addMachineRegEdges (RegToRefVecMap& regToRefVecMap,
const TargetMachine& target);