mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-09-28 22:55:52 +00:00
Factor topological order code to SelectionDAG. Clean up.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@29430 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
9bf2e7f53d
commit
db3cc3d7d6
@ -99,8 +99,7 @@ namespace {
|
|||||||
: SelectionDAGISel(X86Lowering),
|
: SelectionDAGISel(X86Lowering),
|
||||||
X86Lowering(*TM.getTargetLowering()),
|
X86Lowering(*TM.getTargetLowering()),
|
||||||
Subtarget(&TM.getSubtarget<X86Subtarget>()),
|
Subtarget(&TM.getSubtarget<X86Subtarget>()),
|
||||||
DAGSize(0), TopOrder(NULL), IdToOrder(NULL),
|
DAGSize(0) {}
|
||||||
RMRange(NULL), ReachabilityMatrix(NULL) {}
|
|
||||||
|
|
||||||
virtual bool runOnFunction(Function &Fn) {
|
virtual bool runOnFunction(Function &Fn) {
|
||||||
// Make sure we re-emit a set of the global base reg if necessary
|
// Make sure we re-emit a set of the global base reg if necessary
|
||||||
@ -124,7 +123,6 @@ namespace {
|
|||||||
#include "X86GenDAGISel.inc"
|
#include "X86GenDAGISel.inc"
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void DetermineTopologicalOrdering();
|
|
||||||
void DetermineReachability(SDNode *f, SDNode *t);
|
void DetermineReachability(SDNode *f, SDNode *t);
|
||||||
|
|
||||||
void Select(SDOperand &Result, SDOperand N);
|
void Select(SDOperand &Result, SDOperand N);
|
||||||
@ -187,43 +185,37 @@ namespace {
|
|||||||
|
|
||||||
/// TopOrder - Topological ordering of all nodes in the DAG.
|
/// TopOrder - Topological ordering of all nodes in the DAG.
|
||||||
///
|
///
|
||||||
SDNode* *TopOrder;
|
std::vector<SDNode*> TopOrder;
|
||||||
|
|
||||||
/// IdToOrder - Node id to topological order map.
|
/// ReachabilityMatrix - A N x N matrix representing all pairs reachability
|
||||||
///
|
|
||||||
unsigned *IdToOrder;
|
|
||||||
|
|
||||||
/// RMRange - The range of reachibility information available for the
|
|
||||||
/// particular source node.
|
|
||||||
unsigned *RMRange;
|
|
||||||
|
|
||||||
/// ReachabilityMatrix - A N x N matrix representing all pairs reachibility
|
|
||||||
/// information. One bit per potential edge.
|
/// information. One bit per potential edge.
|
||||||
unsigned char *ReachabilityMatrix;
|
std::vector<bool> ReachabilityMatrix;
|
||||||
|
|
||||||
|
/// RMRange - The range of reachability information available for the
|
||||||
|
/// particular source node.
|
||||||
|
std::vector<unsigned> ReachMatrixRange;
|
||||||
|
|
||||||
inline void setReachable(SDNode *f, SDNode *t) {
|
inline void setReachable(SDNode *f, SDNode *t) {
|
||||||
unsigned Idx = f->getNodeId() * DAGSize + t->getNodeId();
|
unsigned Idx = f->getNodeId() * DAGSize + t->getNodeId();
|
||||||
ReachabilityMatrix[Idx / 8] |= 1 << (Idx % 8);
|
ReachabilityMatrix[Idx] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool isReachable(SDNode *f, SDNode *t) {
|
inline bool isReachable(SDNode *f, SDNode *t) {
|
||||||
unsigned Idx = f->getNodeId() * DAGSize + t->getNodeId();
|
unsigned Idx = f->getNodeId() * DAGSize + t->getNodeId();
|
||||||
return ReachabilityMatrix[Idx / 8] & (1 << (Idx % 8));
|
return ReachabilityMatrix[Idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
/// UnfoldableSet - An boolean array representing nodes which have been
|
/// UnfoldableSet - An boolean array representing nodes which have been
|
||||||
/// folded into addressing modes and therefore should not be folded in
|
/// folded into addressing modes and therefore should not be folded in
|
||||||
/// another operation.
|
/// another operation.
|
||||||
unsigned char *UnfoldableSet;
|
std::vector<bool> UnfoldableSet;
|
||||||
|
|
||||||
inline void setUnfoldable(SDNode *N) {
|
inline void setUnfoldable(SDNode *N) {
|
||||||
unsigned Id = N->getNodeId();
|
UnfoldableSet[N->getNodeId()] = true;
|
||||||
UnfoldableSet[Id / 8] |= 1 << (Id % 8);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool isUnfoldable(SDNode *N) {
|
inline bool isUnfoldable(SDNode *N) {
|
||||||
unsigned Id = N->getNodeId();
|
return UnfoldableSet[N->getNodeId()];
|
||||||
return UnfoldableSet[Id / 8] & (1 << (Id % 8));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
@ -259,58 +251,12 @@ bool X86DAGToDAGISel::CanBeFoldedBy(SDNode *N, SDNode *U) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// DetermineTopologicalOrdering - Determine topological ordering of the nodes
|
/// DetermineReachability - Determine reachability between all pairs of nodes
|
||||||
/// in the DAG.
|
|
||||||
void X86DAGToDAGISel::DetermineTopologicalOrdering() {
|
|
||||||
TopOrder = new SDNode*[DAGSize];
|
|
||||||
IdToOrder = new unsigned[DAGSize];
|
|
||||||
memset(IdToOrder, 0, DAGSize * sizeof(unsigned));
|
|
||||||
RMRange = new unsigned[DAGSize];
|
|
||||||
memset(RMRange, 0, DAGSize * sizeof(unsigned));
|
|
||||||
|
|
||||||
std::vector<unsigned> InDegree(DAGSize);
|
|
||||||
std::deque<SDNode*> Sources;
|
|
||||||
for (SelectionDAG::allnodes_iterator I = CurDAG->allnodes_begin(),
|
|
||||||
E = CurDAG->allnodes_end(); I != E; ++I) {
|
|
||||||
SDNode *N = I;
|
|
||||||
unsigned Degree = N->use_size();
|
|
||||||
InDegree[N->getNodeId()] = Degree;
|
|
||||||
if (Degree == 0)
|
|
||||||
Sources.push_back(I);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned Order = 0;
|
|
||||||
while (!Sources.empty()) {
|
|
||||||
SDNode *N = Sources.front();
|
|
||||||
Sources.pop_front();
|
|
||||||
TopOrder[Order] = N;
|
|
||||||
IdToOrder[N->getNodeId()] = Order;
|
|
||||||
Order++;
|
|
||||||
for (SDNode::op_iterator I = N->op_begin(), E = N->op_end(); I != E; ++I) {
|
|
||||||
SDNode *P = I->Val;
|
|
||||||
int PId = P->getNodeId();
|
|
||||||
unsigned Degree = InDegree[PId] - 1;
|
|
||||||
if (Degree == 0)
|
|
||||||
Sources.push_back(P);
|
|
||||||
InDegree[PId] = Degree;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// DetermineReachability - Determine reachibility between all pairs of nodes
|
|
||||||
/// between f and t in topological order.
|
/// between f and t in topological order.
|
||||||
void X86DAGToDAGISel::DetermineReachability(SDNode *f, SDNode *t) {
|
void X86DAGToDAGISel::DetermineReachability(SDNode *f, SDNode *t) {
|
||||||
if (!ReachabilityMatrix) {
|
unsigned Orderf = f->getNodeId();
|
||||||
unsigned RMSize = (DAGSize * DAGSize + 7) / 8;
|
unsigned Ordert = t->getNodeId();
|
||||||
ReachabilityMatrix = new unsigned char[RMSize];
|
unsigned Range = ReachMatrixRange[Orderf];
|
||||||
memset(ReachabilityMatrix, 0, RMSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
int Idf = f->getNodeId();
|
|
||||||
int Idt = t->getNodeId();
|
|
||||||
unsigned Orderf = IdToOrder[Idf];
|
|
||||||
unsigned Ordert = IdToOrder[Idt];
|
|
||||||
unsigned Range = RMRange[Idf];
|
|
||||||
if (Range >= Ordert)
|
if (Range >= Ordert)
|
||||||
return;
|
return;
|
||||||
if (Range < Orderf)
|
if (Range < Orderf)
|
||||||
@ -326,7 +272,7 @@ void X86DAGToDAGISel::DetermineReachability(SDNode *f, SDNode *t) {
|
|||||||
for (unsigned i2 = Orderf; ; ++i2) {
|
for (unsigned i2 = Orderf; ; ++i2) {
|
||||||
SDNode *M = TopOrder[i2];
|
SDNode *M = TopOrder[i2];
|
||||||
if (isReachable(M, N)) {
|
if (isReachable(M, N)) {
|
||||||
// Update reachibility from M to N's operands.
|
// Update reachability from M to N's operands.
|
||||||
for (SDNode::op_iterator I = N->op_begin(), E = N->op_end(); I != E;++I)
|
for (SDNode::op_iterator I = N->op_begin(), E = N->op_end(); I != E;++I)
|
||||||
setReachable(M, I->Val);
|
setReachable(M, I->Val);
|
||||||
}
|
}
|
||||||
@ -334,7 +280,7 @@ void X86DAGToDAGISel::DetermineReachability(SDNode *f, SDNode *t) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RMRange[Idf] = Ordert;
|
ReachMatrixRange[Orderf] = Ordert;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// InstructionSelectBasicBlock - This callback is invoked by SelectionDAGISel
|
/// InstructionSelectBasicBlock - This callback is invoked by SelectionDAGISel
|
||||||
@ -343,12 +289,11 @@ void X86DAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) {
|
|||||||
DEBUG(BB->dump());
|
DEBUG(BB->dump());
|
||||||
MachineFunction::iterator FirstMBB = BB;
|
MachineFunction::iterator FirstMBB = BB;
|
||||||
|
|
||||||
DAGSize = DAG.AssignNodeIds();
|
TopOrder = DAG.AssignTopologicalOrder();
|
||||||
unsigned NumBytes = (DAGSize+7) / 8;
|
DAGSize = TopOrder.size();
|
||||||
UnfoldableSet = new unsigned char[NumBytes];
|
ReachabilityMatrix.assign(DAGSize*DAGSize, false);
|
||||||
memset(UnfoldableSet, 0, NumBytes);
|
ReachMatrixRange.assign(DAGSize, 0);
|
||||||
|
UnfoldableSet.assign(DAGSize, false);
|
||||||
DetermineTopologicalOrdering();
|
|
||||||
|
|
||||||
// Codegen the basic block.
|
// Codegen the basic block.
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
@ -360,15 +305,6 @@ void X86DAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) {
|
|||||||
DEBUG(std::cerr << "===== Instruction selection ends:\n");
|
DEBUG(std::cerr << "===== Instruction selection ends:\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
delete[] ReachabilityMatrix;
|
|
||||||
delete[] TopOrder;
|
|
||||||
delete[] IdToOrder;
|
|
||||||
delete[] RMRange;
|
|
||||||
delete[] UnfoldableSet;
|
|
||||||
ReachabilityMatrix = NULL;
|
|
||||||
TopOrder = NULL;
|
|
||||||
IdToOrder = RMRange = NULL;
|
|
||||||
UnfoldableSet = NULL;
|
|
||||||
CodeGenMap.clear();
|
CodeGenMap.clear();
|
||||||
HandleMap.clear();
|
HandleMap.clear();
|
||||||
ReplaceMap.clear();
|
ReplaceMap.clear();
|
||||||
|
Loading…
Reference in New Issue
Block a user