mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-25 13:24:46 +00:00
Match tablegen isel changes.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@29549 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -26,6 +26,7 @@
|
|||||||
#include "llvm/Target/TargetLowering.h"
|
#include "llvm/Target/TargetLowering.h"
|
||||||
#include "llvm/Support/Debug.h"
|
#include "llvm/Support/Debug.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <queue>
|
||||||
#include <set>
|
#include <set>
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
@@ -306,9 +307,6 @@ void ARMDAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) {
|
|||||||
DEBUG(BB->dump());
|
DEBUG(BB->dump());
|
||||||
|
|
||||||
DAG.setRoot(SelectRoot(DAG.getRoot()));
|
DAG.setRoot(SelectRoot(DAG.getRoot()));
|
||||||
CodeGenMap.clear();
|
|
||||||
HandleMap.clear();
|
|
||||||
ReplaceMap.clear();
|
|
||||||
DAG.RemoveDeadNodes();
|
DAG.RemoveDeadNodes();
|
||||||
|
|
||||||
ScheduleAndEmitDAG(DAG);
|
ScheduleAndEmitDAG(DAG);
|
||||||
|
@@ -30,6 +30,7 @@
|
|||||||
#include "llvm/Support/MathExtras.h"
|
#include "llvm/Support/MathExtras.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <queue>
|
||||||
#include <set>
|
#include <set>
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
@@ -129,7 +130,7 @@ namespace {
|
|||||||
switch (ConstraintCode) {
|
switch (ConstraintCode) {
|
||||||
default: return true;
|
default: return true;
|
||||||
case 'm': // memory
|
case 'm': // memory
|
||||||
Select(Op0, Op);
|
AddToQueue(Op0, Op);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -172,9 +173,6 @@ void AlphaDAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) {
|
|||||||
|
|
||||||
// Select target instructions for the DAG.
|
// Select target instructions for the DAG.
|
||||||
DAG.setRoot(SelectRoot(DAG.getRoot()));
|
DAG.setRoot(SelectRoot(DAG.getRoot()));
|
||||||
CodeGenMap.clear();
|
|
||||||
HandleMap.clear();
|
|
||||||
ReplaceMap.clear();
|
|
||||||
DAG.RemoveDeadNodes();
|
DAG.RemoveDeadNodes();
|
||||||
|
|
||||||
// Emit machine code to BB.
|
// Emit machine code to BB.
|
||||||
@@ -191,13 +189,6 @@ void AlphaDAGToDAGISel::Select(SDOperand &Result, SDOperand Op) {
|
|||||||
return; // Already selected.
|
return; // Already selected.
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this has already been converted, use it.
|
|
||||||
std::map<SDOperand, SDOperand>::iterator CGMI = CodeGenMap.find(Op);
|
|
||||||
if (CGMI != CodeGenMap.end()) {
|
|
||||||
Result = CGMI->second;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (N->getOpcode()) {
|
switch (N->getOpcode()) {
|
||||||
default: break;
|
default: break;
|
||||||
case AlphaISD::CALL:
|
case AlphaISD::CALL:
|
||||||
@@ -213,17 +204,19 @@ void AlphaDAGToDAGISel::Select(SDOperand &Result, SDOperand Op) {
|
|||||||
}
|
}
|
||||||
case AlphaISD::GlobalBaseReg:
|
case AlphaISD::GlobalBaseReg:
|
||||||
Result = getGlobalBaseReg();
|
Result = getGlobalBaseReg();
|
||||||
|
ReplaceUses(Op, Result);
|
||||||
return;
|
return;
|
||||||
case AlphaISD::GlobalRetAddr:
|
case AlphaISD::GlobalRetAddr:
|
||||||
Result = getGlobalRetAddr();
|
Result = getGlobalRetAddr();
|
||||||
|
ReplaceUses(Op, Result);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case AlphaISD::DivCall: {
|
case AlphaISD::DivCall: {
|
||||||
SDOperand Chain = CurDAG->getEntryNode();
|
SDOperand Chain = CurDAG->getEntryNode();
|
||||||
SDOperand N0, N1, N2;
|
SDOperand N0, N1, N2;
|
||||||
Select(N0, Op.getOperand(0));
|
AddToQueue(N0, Op.getOperand(0));
|
||||||
Select(N1, Op.getOperand(1));
|
AddToQueue(N1, Op.getOperand(1));
|
||||||
Select(N2, Op.getOperand(2));
|
AddToQueue(N2, Op.getOperand(2));
|
||||||
Chain = CurDAG->getCopyToReg(Chain, Alpha::R24, N1,
|
Chain = CurDAG->getCopyToReg(Chain, Alpha::R24, N1,
|
||||||
SDOperand(0,0));
|
SDOperand(0,0));
|
||||||
Chain = CurDAG->getCopyToReg(Chain, Alpha::R25, N2,
|
Chain = CurDAG->getCopyToReg(Chain, Alpha::R25, N2,
|
||||||
@@ -241,8 +234,11 @@ void AlphaDAGToDAGISel::Select(SDOperand &Result, SDOperand Op) {
|
|||||||
|
|
||||||
case ISD::READCYCLECOUNTER: {
|
case ISD::READCYCLECOUNTER: {
|
||||||
SDOperand Chain;
|
SDOperand Chain;
|
||||||
Select(Chain, N->getOperand(0)); //Select chain
|
AddToQueue(Chain, N->getOperand(0)); //Select chain
|
||||||
Result = CurDAG->SelectNodeTo(N, Alpha::RPCC, MVT::i64, Chain);
|
Result = SDOperand(CurDAG->getTargetNode(Alpha::RPCC, MVT::i64, MVT::Other,
|
||||||
|
Chain), Op.ResNo);
|
||||||
|
ReplaceUses(Op.getValue(0), Result.getValue(0));
|
||||||
|
ReplaceUses(Op.getValue(1), Result.getValue(1));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -252,6 +248,7 @@ void AlphaDAGToDAGISel::Select(SDOperand &Result, SDOperand Op) {
|
|||||||
if (uval == 0) {
|
if (uval == 0) {
|
||||||
Result = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), Alpha::R31,
|
Result = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), Alpha::R31,
|
||||||
MVT::i64);
|
MVT::i64);
|
||||||
|
ReplaceUses(Op, Result);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -311,8 +308,8 @@ void AlphaDAGToDAGISel::Select(SDOperand &Result, SDOperand Op) {
|
|||||||
case ISD::SETNE: case ISD::SETONE: case ISD::SETUNE: Opc = Alpha::CMPTEQ; isNE = true; break;
|
case ISD::SETNE: case ISD::SETONE: case ISD::SETUNE: Opc = Alpha::CMPTEQ; isNE = true; break;
|
||||||
};
|
};
|
||||||
SDOperand tmp1, tmp2;
|
SDOperand tmp1, tmp2;
|
||||||
Select(tmp1, N->getOperand(0));
|
AddToQueue(tmp1, N->getOperand(0));
|
||||||
Select(tmp2, N->getOperand(1));
|
AddToQueue(tmp2, N->getOperand(1));
|
||||||
SDNode *cmp = CurDAG->getTargetNode(Opc, MVT::f64,
|
SDNode *cmp = CurDAG->getTargetNode(Opc, MVT::f64,
|
||||||
rev?tmp2:tmp1,
|
rev?tmp2:tmp1,
|
||||||
rev?tmp1:tmp2);
|
rev?tmp1:tmp2);
|
||||||
@@ -338,6 +335,7 @@ void AlphaDAGToDAGISel::Select(SDOperand &Result, SDOperand Op) {
|
|||||||
Result = SDOperand(CurDAG->getTargetNode(Alpha::CMPULT, MVT::i64,
|
Result = SDOperand(CurDAG->getTargetNode(Alpha::CMPULT, MVT::i64,
|
||||||
CurDAG->getRegister(Alpha::R31, MVT::i64),
|
CurDAG->getRegister(Alpha::R31, MVT::i64),
|
||||||
LD), 0);
|
LD), 0);
|
||||||
|
ReplaceUses(Op, Result);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -352,9 +350,9 @@ void AlphaDAGToDAGISel::Select(SDOperand &Result, SDOperand Op) {
|
|||||||
//move int to fp
|
//move int to fp
|
||||||
bool isDouble = N->getValueType(0) == MVT::f64;
|
bool isDouble = N->getValueType(0) == MVT::f64;
|
||||||
SDOperand LD, cond, TV, FV;
|
SDOperand LD, cond, TV, FV;
|
||||||
Select(cond, N->getOperand(0));
|
AddToQueue(cond, N->getOperand(0));
|
||||||
Select(TV, N->getOperand(1));
|
AddToQueue(TV, N->getOperand(1));
|
||||||
Select(FV, N->getOperand(2));
|
AddToQueue(FV, N->getOperand(2));
|
||||||
|
|
||||||
if (AlphaLowering.hasITOF()) {
|
if (AlphaLowering.hasITOF()) {
|
||||||
LD = CurDAG->getNode(AlphaISD::ITOFT_, MVT::f64, cond);
|
LD = CurDAG->getNode(AlphaISD::ITOFT_, MVT::f64, cond);
|
||||||
@@ -371,6 +369,7 @@ void AlphaDAGToDAGISel::Select(SDOperand &Result, SDOperand Op) {
|
|||||||
}
|
}
|
||||||
Result = SDOperand(CurDAG->getTargetNode(isDouble?Alpha::FCMOVNET:Alpha::FCMOVNES,
|
Result = SDOperand(CurDAG->getTargetNode(isDouble?Alpha::FCMOVNET:Alpha::FCMOVNES,
|
||||||
MVT::f64, FV, TV, LD), 0);
|
MVT::f64, FV, TV, LD), 0);
|
||||||
|
ReplaceUses(Op, Result);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -396,12 +395,13 @@ void AlphaDAGToDAGISel::Select(SDOperand &Result, SDOperand Op) {
|
|||||||
|
|
||||||
if (get_zapImm(mask)) {
|
if (get_zapImm(mask)) {
|
||||||
SDOperand Src;
|
SDOperand Src;
|
||||||
Select(Src, N->getOperand(0).getOperand(0));
|
AddToQueue(Src, N->getOperand(0).getOperand(0));
|
||||||
SDOperand Z =
|
SDOperand Z =
|
||||||
SDOperand(CurDAG->getTargetNode(Alpha::ZAPNOTi, MVT::i64, Src,
|
SDOperand(CurDAG->getTargetNode(Alpha::ZAPNOTi, MVT::i64, Src,
|
||||||
getI64Imm(get_zapImm(mask))), 0);
|
getI64Imm(get_zapImm(mask))), 0);
|
||||||
Result = SDOperand(CurDAG->getTargetNode(Alpha::SRL, MVT::i64, Z,
|
Result = SDOperand(CurDAG->getTargetNode(Alpha::SRL, MVT::i64, Z,
|
||||||
getI64Imm(sval)), 0);
|
getI64Imm(sval)), 0);
|
||||||
|
ReplaceUses(Op, Result);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -420,7 +420,7 @@ SDOperand AlphaDAGToDAGISel::SelectCALL(SDOperand Op) {
|
|||||||
SDOperand Chain;
|
SDOperand Chain;
|
||||||
SDOperand Addr = N->getOperand(1);
|
SDOperand Addr = N->getOperand(1);
|
||||||
SDOperand InFlag(0,0); // Null incoming flag value.
|
SDOperand InFlag(0,0); // Null incoming flag value.
|
||||||
Select(Chain, N->getOperand(0));
|
AddToQueue(Chain, N->getOperand(0));
|
||||||
|
|
||||||
std::vector<SDOperand> CallOperands;
|
std::vector<SDOperand> CallOperands;
|
||||||
std::vector<MVT::ValueType> TypeOperands;
|
std::vector<MVT::ValueType> TypeOperands;
|
||||||
@@ -429,7 +429,7 @@ SDOperand AlphaDAGToDAGISel::SelectCALL(SDOperand Op) {
|
|||||||
for(int i = 2, e = N->getNumOperands(); i < e; ++i) {
|
for(int i = 2, e = N->getNumOperands(); i < e; ++i) {
|
||||||
SDOperand Tmp;
|
SDOperand Tmp;
|
||||||
TypeOperands.push_back(N->getOperand(i).getValueType());
|
TypeOperands.push_back(N->getOperand(i).getValueType());
|
||||||
Select(Tmp, N->getOperand(i));
|
AddToQueue(Tmp, N->getOperand(i));
|
||||||
CallOperands.push_back(Tmp);
|
CallOperands.push_back(Tmp);
|
||||||
}
|
}
|
||||||
int count = N->getNumOperands() - 2;
|
int count = N->getNumOperands() - 2;
|
||||||
@@ -474,7 +474,7 @@ SDOperand AlphaDAGToDAGISel::SelectCALL(SDOperand Op) {
|
|||||||
Chain = SDOperand(CurDAG->getTargetNode(Alpha::BSR, MVT::Other, MVT::Flag,
|
Chain = SDOperand(CurDAG->getTargetNode(Alpha::BSR, MVT::Other, MVT::Flag,
|
||||||
Addr.getOperand(0), Chain, InFlag), 0);
|
Addr.getOperand(0), Chain, InFlag), 0);
|
||||||
} else {
|
} else {
|
||||||
Select(Addr, Addr);
|
AddToQueue(Addr, Addr);
|
||||||
Chain = CurDAG->getCopyToReg(Chain, Alpha::R27, Addr, InFlag);
|
Chain = CurDAG->getCopyToReg(Chain, Alpha::R27, Addr, InFlag);
|
||||||
InFlag = Chain.getValue(1);
|
InFlag = Chain.getValue(1);
|
||||||
Chain = SDOperand(CurDAG->getTargetNode(Alpha::JSR, MVT::Other, MVT::Flag,
|
Chain = SDOperand(CurDAG->getTargetNode(Alpha::JSR, MVT::Other, MVT::Flag,
|
||||||
@@ -503,7 +503,7 @@ SDOperand AlphaDAGToDAGISel::SelectCALL(SDOperand Op) {
|
|||||||
|
|
||||||
CallResults.push_back(Chain);
|
CallResults.push_back(Chain);
|
||||||
for (unsigned i = 0, e = CallResults.size(); i != e; ++i)
|
for (unsigned i = 0, e = CallResults.size(); i != e; ++i)
|
||||||
CodeGenMap[Op.getValue(i)] = CallResults[i];
|
ReplaceUses(Op.getValue(i), CallResults[i]);
|
||||||
return CallResults[Op.ResNo];
|
return CallResults[Op.ResNo];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -28,6 +28,7 @@
|
|||||||
#include "llvm/Support/Debug.h"
|
#include "llvm/Support/Debug.h"
|
||||||
#include "llvm/Support/MathExtras.h"
|
#include "llvm/Support/MathExtras.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <queue>
|
||||||
#include <set>
|
#include <set>
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
@@ -101,50 +102,9 @@ private:
|
|||||||
/// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
|
/// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
|
||||||
void IA64DAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) {
|
void IA64DAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) {
|
||||||
DEBUG(BB->dump());
|
DEBUG(BB->dump());
|
||||||
|
|
||||||
// The selection process is inherently a bottom-up recursive process (users
|
|
||||||
// select their uses before themselves). Given infinite stack space, we
|
|
||||||
// could just start selecting on the root and traverse the whole graph. In
|
|
||||||
// practice however, this causes us to run out of stack space on large basic
|
|
||||||
// blocks. To avoid this problem, select the entry node, then all its uses,
|
|
||||||
// iteratively instead of recursively.
|
|
||||||
std::vector<SDOperand> Worklist;
|
|
||||||
Worklist.push_back(DAG.getEntryNode());
|
|
||||||
|
|
||||||
// Note that we can do this in the IA64 target (scanning forward across token
|
|
||||||
// chain edges) because no nodes ever get folded across these edges. On a
|
|
||||||
// target like X86 which supports load/modify/store operations, this would
|
|
||||||
// have to be more careful.
|
|
||||||
while (!Worklist.empty()) {
|
|
||||||
SDOperand Node = Worklist.back();
|
|
||||||
Worklist.pop_back();
|
|
||||||
|
|
||||||
if ((Node.Val->getOpcode() >= ISD::BUILTIN_OP_END &&
|
|
||||||
Node.Val->getOpcode() < IA64ISD::FIRST_NUMBER) ||
|
|
||||||
CodeGenMap.count(Node)) continue;
|
|
||||||
|
|
||||||
for (SDNode::use_iterator UI = Node.Val->use_begin(),
|
|
||||||
E = Node.Val->use_end(); UI != E; ++UI) {
|
|
||||||
// Scan the values. If this use has a value that is a token chain, add it
|
|
||||||
// to the worklist.
|
|
||||||
SDNode *User = *UI;
|
|
||||||
for (unsigned i = 0, e = User->getNumValues(); i != e; ++i)
|
|
||||||
if (User->getValueType(i) == MVT::Other) {
|
|
||||||
Worklist.push_back(SDOperand(User, i));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Finally, legalize this node.
|
|
||||||
SDOperand Dummy;
|
|
||||||
Select(Dummy, Node);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Select target instructions for the DAG.
|
// Select target instructions for the DAG.
|
||||||
DAG.setRoot(SelectRoot(DAG.getRoot()));
|
DAG.setRoot(SelectRoot(DAG.getRoot()));
|
||||||
CodeGenMap.clear();
|
|
||||||
HandleMap.clear();
|
|
||||||
ReplaceMap.clear();
|
|
||||||
DAG.RemoveDeadNodes();
|
DAG.RemoveDeadNodes();
|
||||||
|
|
||||||
// Emit machine code to BB.
|
// Emit machine code to BB.
|
||||||
@@ -154,10 +114,10 @@ void IA64DAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) {
|
|||||||
SDOperand IA64DAGToDAGISel::SelectDIV(SDOperand Op) {
|
SDOperand IA64DAGToDAGISel::SelectDIV(SDOperand Op) {
|
||||||
SDNode *N = Op.Val;
|
SDNode *N = Op.Val;
|
||||||
SDOperand Chain, Tmp1, Tmp2;
|
SDOperand Chain, Tmp1, Tmp2;
|
||||||
Select(Chain, N->getOperand(0));
|
AddToQueue(Chain, N->getOperand(0));
|
||||||
|
|
||||||
Select(Tmp1, N->getOperand(0));
|
AddToQueue(Tmp1, N->getOperand(0));
|
||||||
Select(Tmp2, N->getOperand(1));
|
AddToQueue(Tmp2, N->getOperand(1));
|
||||||
|
|
||||||
bool isFP=false;
|
bool isFP=false;
|
||||||
|
|
||||||
@@ -344,13 +304,6 @@ void IA64DAGToDAGISel::Select(SDOperand &Result, SDOperand Op) {
|
|||||||
return; // Already selected.
|
return; // Already selected.
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this has already been converted, use it.
|
|
||||||
std::map<SDOperand, SDOperand>::iterator CGMI = CodeGenMap.find(Op);
|
|
||||||
if (CGMI != CodeGenMap.end()) {
|
|
||||||
Result = CGMI->second;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (N->getOpcode()) {
|
switch (N->getOpcode()) {
|
||||||
default: break;
|
default: break;
|
||||||
|
|
||||||
@@ -358,9 +311,9 @@ void IA64DAGToDAGISel::Select(SDOperand &Result, SDOperand Op) {
|
|||||||
SDOperand Chain;
|
SDOperand Chain;
|
||||||
SDOperand InFlag; // Null incoming flag value.
|
SDOperand InFlag; // Null incoming flag value.
|
||||||
|
|
||||||
Select(Chain, N->getOperand(0));
|
AddToQueue(Chain, N->getOperand(0));
|
||||||
if(N->getNumOperands()==3) // we have an incoming chain, callee and flag
|
if(N->getNumOperands()==3) // we have an incoming chain, callee and flag
|
||||||
Select(InFlag, N->getOperand(2));
|
AddToQueue(InFlag, N->getOperand(2));
|
||||||
|
|
||||||
unsigned CallOpcode;
|
unsigned CallOpcode;
|
||||||
SDOperand CallOperand;
|
SDOperand CallOperand;
|
||||||
@@ -382,7 +335,7 @@ void IA64DAGToDAGISel::Select(SDOperand &Result, SDOperand Op) {
|
|||||||
// load the branch target (function)'s entry point and GP,
|
// load the branch target (function)'s entry point and GP,
|
||||||
// branch (call) then restore the GP
|
// branch (call) then restore the GP
|
||||||
SDOperand FnDescriptor;
|
SDOperand FnDescriptor;
|
||||||
Select(FnDescriptor, N->getOperand(1));
|
AddToQueue(FnDescriptor, N->getOperand(1));
|
||||||
|
|
||||||
// load the branch target's entry point [mem] and
|
// load the branch target's entry point [mem] and
|
||||||
// GP value [mem+8]
|
// GP value [mem+8]
|
||||||
@@ -421,16 +374,16 @@ void IA64DAGToDAGISel::Select(SDOperand &Result, SDOperand Op) {
|
|||||||
CallResults.push_back(InFlag);
|
CallResults.push_back(InFlag);
|
||||||
|
|
||||||
for (unsigned i = 0, e = CallResults.size(); i != e; ++i)
|
for (unsigned i = 0, e = CallResults.size(); i != e; ++i)
|
||||||
CodeGenMap[Op.getValue(i)] = CallResults[i];
|
ReplaceUses(Op.getValue(i), CallResults[i]);
|
||||||
Result = CallResults[Op.ResNo];
|
Result = CallResults[Op.ResNo];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
case IA64ISD::GETFD: {
|
case IA64ISD::GETFD: {
|
||||||
SDOperand Input;
|
SDOperand Input;
|
||||||
Select(Input, N->getOperand(0));
|
AddToQueue(Input, N->getOperand(0));
|
||||||
Result = SDOperand(CurDAG->getTargetNode(IA64::GETFD, MVT::i64, Input), 0);
|
Result = SDOperand(CurDAG->getTargetNode(IA64::GETFD, MVT::i64, Input), 0);
|
||||||
CodeGenMap[Op] = Result;
|
ReplaceUses(Op, Result);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -440,6 +393,7 @@ void IA64DAGToDAGISel::Select(SDOperand &Result, SDOperand Op) {
|
|||||||
case ISD::SREM:
|
case ISD::SREM:
|
||||||
case ISD::UREM:
|
case ISD::UREM:
|
||||||
Result = SelectDIV(Op);
|
Result = SelectDIV(Op);
|
||||||
|
ReplaceUses(Op, Result);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case ISD::TargetConstantFP: {
|
case ISD::TargetConstantFP: {
|
||||||
@@ -459,9 +413,11 @@ void IA64DAGToDAGISel::Select(SDOperand &Result, SDOperand Op) {
|
|||||||
if (N->hasOneUse())
|
if (N->hasOneUse())
|
||||||
Result = CurDAG->SelectNodeTo(N, IA64::MOV, MVT::i64,
|
Result = CurDAG->SelectNodeTo(N, IA64::MOV, MVT::i64,
|
||||||
CurDAG->getTargetFrameIndex(FI, MVT::i64));
|
CurDAG->getTargetFrameIndex(FI, MVT::i64));
|
||||||
else
|
else {
|
||||||
Result = CodeGenMap[Op] = SDOperand(CurDAG->getTargetNode(IA64::MOV, MVT::i64,
|
Result = SDOperand(CurDAG->getTargetNode(IA64::MOV, MVT::i64,
|
||||||
CurDAG->getTargetFrameIndex(FI, MVT::i64)), 0);
|
CurDAG->getTargetFrameIndex(FI, MVT::i64)), 0);
|
||||||
|
ReplaceUses(Op, Result);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -473,6 +429,7 @@ void IA64DAGToDAGISel::Select(SDOperand &Result, SDOperand Op) {
|
|||||||
CP->getAlignment());
|
CP->getAlignment());
|
||||||
Result = SDOperand(CurDAG->getTargetNode(IA64::ADDL_GA, MVT::i64, // ?
|
Result = SDOperand(CurDAG->getTargetNode(IA64::ADDL_GA, MVT::i64, // ?
|
||||||
CurDAG->getRegister(IA64::r1, MVT::i64), CPI), 0);
|
CurDAG->getRegister(IA64::r1, MVT::i64), CPI), 0);
|
||||||
|
ReplaceUses(Op, Result);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -482,6 +439,7 @@ void IA64DAGToDAGISel::Select(SDOperand &Result, SDOperand Op) {
|
|||||||
SDOperand Tmp = SDOperand(CurDAG->getTargetNode(IA64::ADDL_GA, MVT::i64,
|
SDOperand Tmp = SDOperand(CurDAG->getTargetNode(IA64::ADDL_GA, MVT::i64,
|
||||||
CurDAG->getRegister(IA64::r1, MVT::i64), GA), 0);
|
CurDAG->getRegister(IA64::r1, MVT::i64), GA), 0);
|
||||||
Result = SDOperand(CurDAG->getTargetNode(IA64::LD8, MVT::i64, Tmp), 0);
|
Result = SDOperand(CurDAG->getTargetNode(IA64::LD8, MVT::i64, Tmp), 0);
|
||||||
|
ReplaceUses(Op, Result);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -498,8 +456,8 @@ void IA64DAGToDAGISel::Select(SDOperand &Result, SDOperand Op) {
|
|||||||
case ISD::EXTLOAD: // FIXME: load -1, not 1, for bools?
|
case ISD::EXTLOAD: // FIXME: load -1, not 1, for bools?
|
||||||
case ISD::ZEXTLOAD: {
|
case ISD::ZEXTLOAD: {
|
||||||
SDOperand Chain, Address;
|
SDOperand Chain, Address;
|
||||||
Select(Chain, N->getOperand(0));
|
AddToQueue(Chain, N->getOperand(0));
|
||||||
Select(Address, N->getOperand(1));
|
AddToQueue(Address, N->getOperand(1));
|
||||||
|
|
||||||
MVT::ValueType TypeBeingLoaded = (N->getOpcode() == ISD::LOAD) ?
|
MVT::ValueType TypeBeingLoaded = (N->getOpcode() == ISD::LOAD) ?
|
||||||
N->getValueType(0) : cast<VTSDNode>(N->getOperand(3))->getVT();
|
N->getValueType(0) : cast<VTSDNode>(N->getOperand(3))->getVT();
|
||||||
@@ -540,8 +498,8 @@ void IA64DAGToDAGISel::Select(SDOperand &Result, SDOperand Op) {
|
|||||||
case ISD::TRUNCSTORE:
|
case ISD::TRUNCSTORE:
|
||||||
case ISD::STORE: {
|
case ISD::STORE: {
|
||||||
SDOperand Address, Chain;
|
SDOperand Address, Chain;
|
||||||
Select(Address, N->getOperand(2));
|
AddToQueue(Address, N->getOperand(2));
|
||||||
Select(Chain, N->getOperand(0));
|
AddToQueue(Chain, N->getOperand(0));
|
||||||
|
|
||||||
unsigned Opc;
|
unsigned Opc;
|
||||||
if (N->getOpcode() == ISD::STORE) {
|
if (N->getOpcode() == ISD::STORE) {
|
||||||
@@ -554,7 +512,7 @@ void IA64DAGToDAGISel::Select(SDOperand &Result, SDOperand Op) {
|
|||||||
Chain = Initial.getValue(1);
|
Chain = Initial.getValue(1);
|
||||||
// then load 1 into the same reg iff the predicate to store is 1
|
// then load 1 into the same reg iff the predicate to store is 1
|
||||||
SDOperand Tmp;
|
SDOperand Tmp;
|
||||||
Select(Tmp, N->getOperand(1));
|
AddToQueue(Tmp, N->getOperand(1));
|
||||||
Tmp = SDOperand(CurDAG->getTargetNode(IA64::TPCADDS, MVT::i64, Initial,
|
Tmp = SDOperand(CurDAG->getTargetNode(IA64::TPCADDS, MVT::i64, Initial,
|
||||||
CurDAG->getConstant(1, MVT::i64),
|
CurDAG->getConstant(1, MVT::i64),
|
||||||
Tmp), 0);
|
Tmp), 0);
|
||||||
@@ -575,16 +533,16 @@ void IA64DAGToDAGISel::Select(SDOperand &Result, SDOperand Op) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SDOperand N1, N2;
|
SDOperand N1, N2;
|
||||||
Select(N1, N->getOperand(1));
|
AddToQueue(N1, N->getOperand(1));
|
||||||
Select(N2, N->getOperand(2));
|
AddToQueue(N2, N->getOperand(2));
|
||||||
Result = CurDAG->SelectNodeTo(N, Opc, MVT::Other, N2, N1, Chain);
|
Result = CurDAG->SelectNodeTo(N, Opc, MVT::Other, N2, N1, Chain);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
case ISD::BRCOND: {
|
case ISD::BRCOND: {
|
||||||
SDOperand Chain, CC;
|
SDOperand Chain, CC;
|
||||||
Select(Chain, N->getOperand(0));
|
AddToQueue(Chain, N->getOperand(0));
|
||||||
Select(CC, N->getOperand(1));
|
AddToQueue(CC, N->getOperand(1));
|
||||||
MachineBasicBlock *Dest =
|
MachineBasicBlock *Dest =
|
||||||
cast<BasicBlockSDNode>(N->getOperand(2))->getBasicBlock();
|
cast<BasicBlockSDNode>(N->getOperand(2))->getBasicBlock();
|
||||||
//FIXME - we do NOT need long branches all the time
|
//FIXME - we do NOT need long branches all the time
|
||||||
@@ -599,7 +557,7 @@ void IA64DAGToDAGISel::Select(SDOperand &Result, SDOperand Op) {
|
|||||||
unsigned Opc = N->getOpcode() == ISD::CALLSEQ_START ?
|
unsigned Opc = N->getOpcode() == ISD::CALLSEQ_START ?
|
||||||
IA64::ADJUSTCALLSTACKDOWN : IA64::ADJUSTCALLSTACKUP;
|
IA64::ADJUSTCALLSTACKDOWN : IA64::ADJUSTCALLSTACKUP;
|
||||||
SDOperand N0;
|
SDOperand N0;
|
||||||
Select(N0, N->getOperand(0));
|
AddToQueue(N0, N->getOperand(0));
|
||||||
Result = CurDAG->SelectNodeTo(N, Opc, MVT::Other, getI64Imm(Amt), N0);
|
Result = CurDAG->SelectNodeTo(N, Opc, MVT::Other, getI64Imm(Amt), N0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -607,7 +565,7 @@ void IA64DAGToDAGISel::Select(SDOperand &Result, SDOperand Op) {
|
|||||||
case ISD::BR:
|
case ISD::BR:
|
||||||
// FIXME: we don't need long branches all the time!
|
// FIXME: we don't need long branches all the time!
|
||||||
SDOperand N0;
|
SDOperand N0;
|
||||||
Select(N0, N->getOperand(0));
|
AddToQueue(N0, N->getOperand(0));
|
||||||
Result = CurDAG->SelectNodeTo(N, IA64::BRL_NOTCALL, MVT::Other,
|
Result = CurDAG->SelectNodeTo(N, IA64::BRL_NOTCALL, MVT::Other,
|
||||||
N->getOperand(1), N0);
|
N->getOperand(1), N0);
|
||||||
return;
|
return;
|
||||||
|
@@ -30,6 +30,7 @@
|
|||||||
#include "llvm/Support/MathExtras.h"
|
#include "llvm/Support/MathExtras.h"
|
||||||
#include "llvm/Support/Visibility.h"
|
#include "llvm/Support/Visibility.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <queue>
|
||||||
#include <set>
|
#include <set>
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
@@ -123,7 +124,7 @@ namespace {
|
|||||||
break;
|
break;
|
||||||
case 'o': // offsetable
|
case 'o': // offsetable
|
||||||
if (!SelectAddrImm(Op, Op0, Op1)) {
|
if (!SelectAddrImm(Op, Op0, Op1)) {
|
||||||
Select(Op0, Op); // r+0.
|
AddToQueue(Op0, Op); // r+0.
|
||||||
Op1 = getSmallIPtrImm(0);
|
Op1 = getSmallIPtrImm(0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -174,50 +175,9 @@ private:
|
|||||||
/// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
|
/// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
|
||||||
void PPCDAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) {
|
void PPCDAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) {
|
||||||
DEBUG(BB->dump());
|
DEBUG(BB->dump());
|
||||||
|
|
||||||
// The selection process is inherently a bottom-up recursive process (users
|
|
||||||
// select their uses before themselves). Given infinite stack space, we
|
|
||||||
// could just start selecting on the root and traverse the whole graph. In
|
|
||||||
// practice however, this causes us to run out of stack space on large basic
|
|
||||||
// blocks. To avoid this problem, select the entry node, then all its uses,
|
|
||||||
// iteratively instead of recursively.
|
|
||||||
std::vector<SDOperand> Worklist;
|
|
||||||
Worklist.push_back(DAG.getEntryNode());
|
|
||||||
|
|
||||||
// Note that we can do this in the PPC target (scanning forward across token
|
|
||||||
// chain edges) because no nodes ever get folded across these edges. On a
|
|
||||||
// target like X86 which supports load/modify/store operations, this would
|
|
||||||
// have to be more careful.
|
|
||||||
while (!Worklist.empty()) {
|
|
||||||
SDOperand Node = Worklist.back();
|
|
||||||
Worklist.pop_back();
|
|
||||||
|
|
||||||
if ((Node.Val->getOpcode() >= ISD::BUILTIN_OP_END &&
|
|
||||||
Node.Val->getOpcode() < PPCISD::FIRST_NUMBER) ||
|
|
||||||
CodeGenMap.count(Node)) continue;
|
|
||||||
|
|
||||||
for (SDNode::use_iterator UI = Node.Val->use_begin(),
|
|
||||||
E = Node.Val->use_end(); UI != E; ++UI) {
|
|
||||||
// Scan the values. If this use has a value that is a token chain, add it
|
|
||||||
// to the worklist.
|
|
||||||
SDNode *User = *UI;
|
|
||||||
for (unsigned i = 0, e = User->getNumValues(); i != e; ++i)
|
|
||||||
if (User->getValueType(i) == MVT::Other) {
|
|
||||||
Worklist.push_back(SDOperand(User, i));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Finally, legalize this node.
|
|
||||||
SDOperand Dummy;
|
|
||||||
Select(Dummy, Node);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Select target instructions for the DAG.
|
// Select target instructions for the DAG.
|
||||||
DAG.setRoot(SelectRoot(DAG.getRoot()));
|
DAG.setRoot(SelectRoot(DAG.getRoot()));
|
||||||
CodeGenMap.clear();
|
|
||||||
HandleMap.clear();
|
|
||||||
ReplaceMap.clear();
|
|
||||||
DAG.RemoveDeadNodes();
|
DAG.RemoveDeadNodes();
|
||||||
|
|
||||||
// Emit machine code to BB.
|
// Emit machine code to BB.
|
||||||
@@ -493,8 +453,8 @@ SDNode *PPCDAGToDAGISel::SelectBitfieldInsert(SDNode *N) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Tmp3 = (Op0Opc == ISD::AND && DisjointMask) ? Op0.getOperand(0) : Op0;
|
Tmp3 = (Op0Opc == ISD::AND && DisjointMask) ? Op0.getOperand(0) : Op0;
|
||||||
Select(Tmp1, Tmp3);
|
AddToQueue(Tmp1, Tmp3);
|
||||||
Select(Tmp2, Op1);
|
AddToQueue(Tmp2, Op1);
|
||||||
SH &= 31;
|
SH &= 31;
|
||||||
return CurDAG->getTargetNode(PPC::RLWIMI, MVT::i32, Tmp1, Tmp2,
|
return CurDAG->getTargetNode(PPC::RLWIMI, MVT::i32, Tmp1, Tmp2,
|
||||||
getI32Imm(SH), getI32Imm(MB), getI32Imm(ME));
|
getI32Imm(SH), getI32Imm(MB), getI32Imm(ME));
|
||||||
@@ -732,7 +692,7 @@ bool PPCDAGToDAGISel::SelectAddrImmShift(SDOperand N, SDOperand &Disp,
|
|||||||
SDOperand PPCDAGToDAGISel::SelectCC(SDOperand LHS, SDOperand RHS,
|
SDOperand PPCDAGToDAGISel::SelectCC(SDOperand LHS, SDOperand RHS,
|
||||||
ISD::CondCode CC) {
|
ISD::CondCode CC) {
|
||||||
// Always select the LHS.
|
// Always select the LHS.
|
||||||
Select(LHS, LHS);
|
AddToQueue(LHS, LHS);
|
||||||
unsigned Opc;
|
unsigned Opc;
|
||||||
|
|
||||||
if (LHS.getValueType() == MVT::i32) {
|
if (LHS.getValueType() == MVT::i32) {
|
||||||
@@ -771,7 +731,7 @@ SDOperand PPCDAGToDAGISel::SelectCC(SDOperand LHS, SDOperand RHS,
|
|||||||
assert(LHS.getValueType() == MVT::f64 && "Unknown vt!");
|
assert(LHS.getValueType() == MVT::f64 && "Unknown vt!");
|
||||||
Opc = PPC::FCMPUD;
|
Opc = PPC::FCMPUD;
|
||||||
}
|
}
|
||||||
Select(RHS, RHS);
|
AddToQueue(RHS, RHS);
|
||||||
return SDOperand(CurDAG->getTargetNode(Opc, MVT::i32, LHS, RHS), 0);
|
return SDOperand(CurDAG->getTargetNode(Opc, MVT::i32, LHS, RHS), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -845,7 +805,7 @@ SDOperand PPCDAGToDAGISel::SelectSETCC(SDOperand Op) {
|
|||||||
// setcc op, 0
|
// setcc op, 0
|
||||||
if (Imm == 0) {
|
if (Imm == 0) {
|
||||||
SDOperand Op;
|
SDOperand Op;
|
||||||
Select(Op, N->getOperand(0));
|
AddToQueue(Op, N->getOperand(0));
|
||||||
switch (CC) {
|
switch (CC) {
|
||||||
default: break;
|
default: break;
|
||||||
case ISD::SETEQ:
|
case ISD::SETEQ:
|
||||||
@@ -872,7 +832,7 @@ SDOperand PPCDAGToDAGISel::SelectSETCC(SDOperand Op) {
|
|||||||
}
|
}
|
||||||
} else if (Imm == ~0U) { // setcc op, -1
|
} else if (Imm == ~0U) { // setcc op, -1
|
||||||
SDOperand Op;
|
SDOperand Op;
|
||||||
Select(Op, N->getOperand(0));
|
AddToQueue(Op, N->getOperand(0));
|
||||||
switch (CC) {
|
switch (CC) {
|
||||||
default: break;
|
default: break;
|
||||||
case ISD::SETEQ:
|
case ISD::SETEQ:
|
||||||
@@ -948,13 +908,6 @@ void PPCDAGToDAGISel::Select(SDOperand &Result, SDOperand Op) {
|
|||||||
return; // Already selected.
|
return; // Already selected.
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this has already been converted, use it.
|
|
||||||
std::map<SDOperand, SDOperand>::iterator CGMI = CodeGenMap.find(Op);
|
|
||||||
if (CGMI != CodeGenMap.end()) {
|
|
||||||
Result = CGMI->second;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (N->getOpcode()) {
|
switch (N->getOpcode()) {
|
||||||
default: break;
|
default: break;
|
||||||
case ISD::SETCC:
|
case ISD::SETCC:
|
||||||
@@ -962,6 +915,7 @@ void PPCDAGToDAGISel::Select(SDOperand &Result, SDOperand Op) {
|
|||||||
return;
|
return;
|
||||||
case PPCISD::GlobalBaseReg:
|
case PPCISD::GlobalBaseReg:
|
||||||
Result = getGlobalBaseReg();
|
Result = getGlobalBaseReg();
|
||||||
|
ReplaceUses(Op, Result);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case ISD::FrameIndex: {
|
case ISD::FrameIndex: {
|
||||||
@@ -973,22 +927,23 @@ void PPCDAGToDAGISel::Select(SDOperand &Result, SDOperand Op) {
|
|||||||
getSmallIPtrImm(0));
|
getSmallIPtrImm(0));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Result = CodeGenMap[Op] =
|
Result =
|
||||||
SDOperand(CurDAG->getTargetNode(Opc, Op.getValueType(), TFI,
|
SDOperand(CurDAG->getTargetNode(Opc, Op.getValueType(), TFI,
|
||||||
getSmallIPtrImm(0)), 0);
|
getSmallIPtrImm(0)), 0);
|
||||||
|
ReplaceUses(Op, Result);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
case PPCISD::MFCR: {
|
case PPCISD::MFCR: {
|
||||||
SDOperand InFlag;
|
SDOperand InFlag;
|
||||||
Select(InFlag, N->getOperand(1));
|
AddToQueue(InFlag, N->getOperand(1));
|
||||||
// Use MFOCRF if supported.
|
// Use MFOCRF if supported.
|
||||||
if (TLI.getTargetMachine().getSubtarget<PPCSubtarget>().isGigaProcessor())
|
if (TLI.getTargetMachine().getSubtarget<PPCSubtarget>().isGigaProcessor())
|
||||||
Result = SDOperand(CurDAG->getTargetNode(PPC::MFOCRF, MVT::i32,
|
Result = SDOperand(CurDAG->getTargetNode(PPC::MFOCRF, MVT::i32,
|
||||||
N->getOperand(0), InFlag), 0);
|
N->getOperand(0), InFlag), 0);
|
||||||
else
|
else
|
||||||
Result = SDOperand(CurDAG->getTargetNode(PPC::MFCR, MVT::i32, InFlag), 0);
|
Result = SDOperand(CurDAG->getTargetNode(PPC::MFCR, MVT::i32, InFlag), 0);
|
||||||
CodeGenMap[Op] = Result;
|
ReplaceUses(Op, Result);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1001,7 +956,7 @@ void PPCDAGToDAGISel::Select(SDOperand &Result, SDOperand Op) {
|
|||||||
unsigned Imm;
|
unsigned Imm;
|
||||||
if (isInt32Immediate(N->getOperand(1), Imm)) {
|
if (isInt32Immediate(N->getOperand(1), Imm)) {
|
||||||
SDOperand N0;
|
SDOperand N0;
|
||||||
Select(N0, N->getOperand(0));
|
AddToQueue(N0, N->getOperand(0));
|
||||||
if ((signed)Imm > 0 && isPowerOf2_32(Imm)) {
|
if ((signed)Imm > 0 && isPowerOf2_32(Imm)) {
|
||||||
SDNode *Op =
|
SDNode *Op =
|
||||||
CurDAG->getTargetNode(PPC::SRAWI, MVT::i32, MVT::Flag,
|
CurDAG->getTargetNode(PPC::SRAWI, MVT::i32, MVT::Flag,
|
||||||
@@ -1033,13 +988,13 @@ void PPCDAGToDAGISel::Select(SDOperand &Result, SDOperand Op) {
|
|||||||
SDOperand Val;
|
SDOperand Val;
|
||||||
unsigned SH, MB, ME;
|
unsigned SH, MB, ME;
|
||||||
if (isRotateAndMask(N->getOperand(0).Val, Imm, false, SH, MB, ME)) {
|
if (isRotateAndMask(N->getOperand(0).Val, Imm, false, SH, MB, ME)) {
|
||||||
Select(Val, N->getOperand(0).getOperand(0));
|
AddToQueue(Val, N->getOperand(0).getOperand(0));
|
||||||
} else if (Imm == 0) {
|
} else if (Imm == 0) {
|
||||||
// AND X, 0 -> 0, not "rlwinm 32".
|
// AND X, 0 -> 0, not "rlwinm 32".
|
||||||
Select(Result, N->getOperand(1));
|
AddToQueue(Result, N->getOperand(1));
|
||||||
return ;
|
return ;
|
||||||
} else {
|
} else {
|
||||||
Select(Val, N->getOperand(0));
|
AddToQueue(Val, N->getOperand(0));
|
||||||
isRunOfOnes(Imm, MB, ME);
|
isRunOfOnes(Imm, MB, ME);
|
||||||
SH = 0;
|
SH = 0;
|
||||||
}
|
}
|
||||||
@@ -1057,12 +1012,13 @@ void PPCDAGToDAGISel::Select(SDOperand &Result, SDOperand Op) {
|
|||||||
Imm = ~(Imm^Imm2);
|
Imm = ~(Imm^Imm2);
|
||||||
if (isRunOfOnes(Imm, MB, ME)) {
|
if (isRunOfOnes(Imm, MB, ME)) {
|
||||||
SDOperand Tmp1, Tmp2;
|
SDOperand Tmp1, Tmp2;
|
||||||
Select(Tmp1, N->getOperand(0).getOperand(0));
|
AddToQueue(Tmp1, N->getOperand(0).getOperand(0));
|
||||||
Select(Tmp2, N->getOperand(0).getOperand(1));
|
AddToQueue(Tmp2, N->getOperand(0).getOperand(1));
|
||||||
Result = SDOperand(CurDAG->getTargetNode(PPC::RLWIMI, MVT::i32,
|
Result = SDOperand(CurDAG->getTargetNode(PPC::RLWIMI, MVT::i32,
|
||||||
Tmp1, Tmp2,
|
Tmp1, Tmp2,
|
||||||
getI32Imm(0), getI32Imm(MB),
|
getI32Imm(0), getI32Imm(MB),
|
||||||
getI32Imm(ME)), 0);
|
getI32Imm(ME)), 0);
|
||||||
|
ReplaceUses(Op, Result);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1073,7 +1029,8 @@ void PPCDAGToDAGISel::Select(SDOperand &Result, SDOperand Op) {
|
|||||||
case ISD::OR:
|
case ISD::OR:
|
||||||
if (N->getValueType(0) == MVT::i32)
|
if (N->getValueType(0) == MVT::i32)
|
||||||
if (SDNode *I = SelectBitfieldInsert(N)) {
|
if (SDNode *I = SelectBitfieldInsert(N)) {
|
||||||
Result = CodeGenMap[Op] = SDOperand(I, 0);
|
Result = SDOperand(I, 0);
|
||||||
|
ReplaceUses(Op, Result);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1084,7 +1041,7 @@ void PPCDAGToDAGISel::Select(SDOperand &Result, SDOperand Op) {
|
|||||||
if (isOpcWithIntImmediate(N->getOperand(0).Val, ISD::AND, Imm) &&
|
if (isOpcWithIntImmediate(N->getOperand(0).Val, ISD::AND, Imm) &&
|
||||||
isRotateAndMask(N, Imm, true, SH, MB, ME)) {
|
isRotateAndMask(N, Imm, true, SH, MB, ME)) {
|
||||||
SDOperand Val;
|
SDOperand Val;
|
||||||
Select(Val, N->getOperand(0).getOperand(0));
|
AddToQueue(Val, N->getOperand(0).getOperand(0));
|
||||||
Result = CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32,
|
Result = CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32,
|
||||||
Val, getI32Imm(SH), getI32Imm(MB),
|
Val, getI32Imm(SH), getI32Imm(MB),
|
||||||
getI32Imm(ME));
|
getI32Imm(ME));
|
||||||
@@ -1099,7 +1056,7 @@ void PPCDAGToDAGISel::Select(SDOperand &Result, SDOperand Op) {
|
|||||||
if (isOpcWithIntImmediate(N->getOperand(0).Val, ISD::AND, Imm) &&
|
if (isOpcWithIntImmediate(N->getOperand(0).Val, ISD::AND, Imm) &&
|
||||||
isRotateAndMask(N, Imm, true, SH, MB, ME)) {
|
isRotateAndMask(N, Imm, true, SH, MB, ME)) {
|
||||||
SDOperand Val;
|
SDOperand Val;
|
||||||
Select(Val, N->getOperand(0).getOperand(0));
|
AddToQueue(Val, N->getOperand(0).getOperand(0));
|
||||||
Result = CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32,
|
Result = CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32,
|
||||||
Val, getI32Imm(SH), getI32Imm(MB),
|
Val, getI32Imm(SH), getI32Imm(MB),
|
||||||
getI32Imm(ME));
|
getI32Imm(ME));
|
||||||
@@ -1121,7 +1078,7 @@ void PPCDAGToDAGISel::Select(SDOperand &Result, SDOperand Op) {
|
|||||||
// FIXME: Implement this optzn for PPC64.
|
// FIXME: Implement this optzn for PPC64.
|
||||||
N->getValueType(0) == MVT::i32) {
|
N->getValueType(0) == MVT::i32) {
|
||||||
SDOperand LHS;
|
SDOperand LHS;
|
||||||
Select(LHS, N->getOperand(0));
|
AddToQueue(LHS, N->getOperand(0));
|
||||||
SDNode *Tmp =
|
SDNode *Tmp =
|
||||||
CurDAG->getTargetNode(PPC::ADDIC, MVT::i32, MVT::Flag,
|
CurDAG->getTargetNode(PPC::ADDIC, MVT::i32, MVT::Flag,
|
||||||
LHS, getI32Imm(~0U));
|
LHS, getI32Imm(~0U));
|
||||||
@@ -1148,15 +1105,15 @@ void PPCDAGToDAGISel::Select(SDOperand &Result, SDOperand Op) {
|
|||||||
SelectCCOp = PPC::SELECT_CC_VRRC;
|
SelectCCOp = PPC::SELECT_CC_VRRC;
|
||||||
|
|
||||||
SDOperand N2, N3;
|
SDOperand N2, N3;
|
||||||
Select(N2, N->getOperand(2));
|
AddToQueue(N2, N->getOperand(2));
|
||||||
Select(N3, N->getOperand(3));
|
AddToQueue(N3, N->getOperand(3));
|
||||||
Result = CurDAG->SelectNodeTo(N, SelectCCOp, N->getValueType(0), CCReg,
|
Result = CurDAG->SelectNodeTo(N, SelectCCOp, N->getValueType(0), CCReg,
|
||||||
N2, N3, getI32Imm(BROpc));
|
N2, N3, getI32Imm(BROpc));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case ISD::BR_CC: {
|
case ISD::BR_CC: {
|
||||||
SDOperand Chain;
|
SDOperand Chain;
|
||||||
Select(Chain, N->getOperand(0));
|
AddToQueue(Chain, N->getOperand(0));
|
||||||
ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(1))->get();
|
ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(1))->get();
|
||||||
SDOperand CondCode = SelectCC(N->getOperand(2), N->getOperand(3), CC);
|
SDOperand CondCode = SelectCC(N->getOperand(2), N->getOperand(3), CC);
|
||||||
Result = CurDAG->SelectNodeTo(N, PPC::COND_BRANCH, MVT::Other,
|
Result = CurDAG->SelectNodeTo(N, PPC::COND_BRANCH, MVT::Other,
|
||||||
@@ -1167,8 +1124,8 @@ void PPCDAGToDAGISel::Select(SDOperand &Result, SDOperand Op) {
|
|||||||
case ISD::BRIND: {
|
case ISD::BRIND: {
|
||||||
// FIXME: Should custom lower this.
|
// FIXME: Should custom lower this.
|
||||||
SDOperand Chain, Target;
|
SDOperand Chain, Target;
|
||||||
Select(Chain, N->getOperand(0));
|
AddToQueue(Chain, N->getOperand(0));
|
||||||
Select(Target,N->getOperand(1));
|
AddToQueue(Target,N->getOperand(1));
|
||||||
unsigned Opc = Target.getValueType() == MVT::i32 ? PPC::MTCTR : PPC::MTCTR8;
|
unsigned Opc = Target.getValueType() == MVT::i32 ? PPC::MTCTR : PPC::MTCTR8;
|
||||||
Chain = SDOperand(CurDAG->getTargetNode(Opc, MVT::Other, Target,
|
Chain = SDOperand(CurDAG->getTargetNode(Opc, MVT::Other, Target,
|
||||||
Chain), 0);
|
Chain), 0);
|
||||||
@@ -1198,25 +1155,23 @@ void PPCDAGToDAGISel::MySelect_PPCbctrl(SDOperand &Result, SDOperand N) {
|
|||||||
std::vector<SDOperand> Ops;
|
std::vector<SDOperand> Ops;
|
||||||
// Push varargs arguments, including optional flag.
|
// Push varargs arguments, including optional flag.
|
||||||
for (unsigned i = 1, e = N.getNumOperands()-hasFlag; i != e; ++i) {
|
for (unsigned i = 1, e = N.getNumOperands()-hasFlag; i != e; ++i) {
|
||||||
Select(Chain, N.getOperand(i));
|
AddToQueue(Chain, N.getOperand(i));
|
||||||
Ops.push_back(Chain);
|
Ops.push_back(Chain);
|
||||||
}
|
}
|
||||||
|
|
||||||
Select(Chain, N.getOperand(0));
|
AddToQueue(Chain, N.getOperand(0));
|
||||||
Ops.push_back(Chain);
|
Ops.push_back(Chain);
|
||||||
|
|
||||||
if (hasFlag) {
|
if (hasFlag) {
|
||||||
Select(Chain, N.getOperand(N.getNumOperands()-1));
|
AddToQueue(Chain, N.getOperand(N.getNumOperands()-1));
|
||||||
Ops.push_back(Chain);
|
Ops.push_back(Chain);
|
||||||
}
|
}
|
||||||
|
|
||||||
ResNode = CurDAG->getTargetNode(PPC::BCTRL, MVT::Other, MVT::Flag, Ops);
|
ResNode = CurDAG->getTargetNode(PPC::BCTRL, MVT::Other, MVT::Flag, Ops);
|
||||||
Chain = SDOperand(ResNode, 0);
|
Chain = SDOperand(ResNode, 0);
|
||||||
InFlag = SDOperand(ResNode, 1);
|
InFlag = SDOperand(ResNode, 1);
|
||||||
SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, 0, Chain.Val,
|
ReplaceUses(SDOperand(N.Val, 0), Chain);
|
||||||
Chain.ResNo);
|
ReplaceUses(SDOperand(N.Val, 1), InFlag);
|
||||||
SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, 1, InFlag.Val,
|
|
||||||
InFlag.ResNo);
|
|
||||||
Result = SDOperand(ResNode, N.ResNo);
|
Result = SDOperand(ResNode, N.ResNo);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1246,23 +1201,21 @@ void PPCDAGToDAGISel::MySelect_PPCcall(SDOperand &Result, SDOperand N) {
|
|||||||
|
|
||||||
// Push varargs arguments, not including optional flag.
|
// Push varargs arguments, not including optional flag.
|
||||||
for (unsigned i = 2, e = N.getNumOperands()-hasFlag; i != e; ++i) {
|
for (unsigned i = 2, e = N.getNumOperands()-hasFlag; i != e; ++i) {
|
||||||
Select(Chain, N.getOperand(i));
|
AddToQueue(Chain, N.getOperand(i));
|
||||||
Ops.push_back(Chain);
|
Ops.push_back(Chain);
|
||||||
}
|
}
|
||||||
Select(Chain, N.getOperand(0));
|
AddToQueue(Chain, N.getOperand(0));
|
||||||
Ops.push_back(Chain);
|
Ops.push_back(Chain);
|
||||||
if (hasFlag) {
|
if (hasFlag) {
|
||||||
Select(Chain, N.getOperand(N.getNumOperands()-1));
|
AddToQueue(Chain, N.getOperand(N.getNumOperands()-1));
|
||||||
Ops.push_back(Chain);
|
Ops.push_back(Chain);
|
||||||
}
|
}
|
||||||
ResNode = CurDAG->getTargetNode(PPC::BLA, MVT::Other, MVT::Flag, Ops);
|
ResNode = CurDAG->getTargetNode(PPC::BLA, MVT::Other, MVT::Flag, Ops);
|
||||||
|
|
||||||
Chain = SDOperand(ResNode, 0);
|
Chain = SDOperand(ResNode, 0);
|
||||||
InFlag = SDOperand(ResNode, 1);
|
InFlag = SDOperand(ResNode, 1);
|
||||||
SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, 0, Chain.Val,
|
ReplaceUses(SDOperand(N.Val, 0), Chain);
|
||||||
Chain.ResNo);
|
ReplaceUses(SDOperand(N.Val, 1), InFlag);
|
||||||
SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, 1, InFlag.Val,
|
|
||||||
InFlag.ResNo);
|
|
||||||
Result = SDOperand(ResNode, N.ResNo);
|
Result = SDOperand(ResNode, N.ResNo);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1279,13 +1232,13 @@ void PPCDAGToDAGISel::MySelect_PPCcall(SDOperand &Result, SDOperand N) {
|
|||||||
|
|
||||||
// Push varargs arguments, not including optional flag.
|
// Push varargs arguments, not including optional flag.
|
||||||
for (unsigned i = 2, e = N.getNumOperands()-hasFlag; i != e; ++i) {
|
for (unsigned i = 2, e = N.getNumOperands()-hasFlag; i != e; ++i) {
|
||||||
Select(Chain, N.getOperand(i));
|
AddToQueue(Chain, N.getOperand(i));
|
||||||
Ops.push_back(Chain);
|
Ops.push_back(Chain);
|
||||||
}
|
}
|
||||||
Select(Chain, N.getOperand(0));
|
AddToQueue(Chain, N.getOperand(0));
|
||||||
Ops.push_back(Chain);
|
Ops.push_back(Chain);
|
||||||
if (hasFlag) {
|
if (hasFlag) {
|
||||||
Select(Chain, N.getOperand(N.getNumOperands()-1));
|
AddToQueue(Chain, N.getOperand(N.getNumOperands()-1));
|
||||||
Ops.push_back(Chain);
|
Ops.push_back(Chain);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1293,10 +1246,8 @@ void PPCDAGToDAGISel::MySelect_PPCcall(SDOperand &Result, SDOperand N) {
|
|||||||
|
|
||||||
Chain = SDOperand(ResNode, 0);
|
Chain = SDOperand(ResNode, 0);
|
||||||
InFlag = SDOperand(ResNode, 1);
|
InFlag = SDOperand(ResNode, 1);
|
||||||
SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, 0, Chain.Val,
|
ReplaceUses(SDOperand(N.Val, 0), Chain);
|
||||||
Chain.ResNo);
|
ReplaceUses(SDOperand(N.Val, 1), InFlag);
|
||||||
SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, 1, InFlag.Val,
|
|
||||||
InFlag.ResNo);
|
|
||||||
Result = SDOperand(ResNode, N.ResNo);
|
Result = SDOperand(ResNode, N.ResNo);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1313,13 +1264,13 @@ void PPCDAGToDAGISel::MySelect_PPCcall(SDOperand &Result, SDOperand N) {
|
|||||||
|
|
||||||
// Push varargs arguments, not including optional flag.
|
// Push varargs arguments, not including optional flag.
|
||||||
for (unsigned i = 2, e = N.getNumOperands()-hasFlag; i != e; ++i) {
|
for (unsigned i = 2, e = N.getNumOperands()-hasFlag; i != e; ++i) {
|
||||||
Select(Chain, N.getOperand(i));
|
AddToQueue(Chain, N.getOperand(i));
|
||||||
Ops.push_back(Chain);
|
Ops.push_back(Chain);
|
||||||
}
|
}
|
||||||
Select(Chain, N.getOperand(0));
|
AddToQueue(Chain, N.getOperand(0));
|
||||||
Ops.push_back(Chain);
|
Ops.push_back(Chain);
|
||||||
if (hasFlag) {
|
if (hasFlag) {
|
||||||
Select(Chain, N.getOperand(N.getNumOperands()-1));
|
AddToQueue(Chain, N.getOperand(N.getNumOperands()-1));
|
||||||
Ops.push_back(Chain);
|
Ops.push_back(Chain);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1327,10 +1278,8 @@ void PPCDAGToDAGISel::MySelect_PPCcall(SDOperand &Result, SDOperand N) {
|
|||||||
|
|
||||||
Chain = SDOperand(ResNode, 0);
|
Chain = SDOperand(ResNode, 0);
|
||||||
InFlag = SDOperand(ResNode, 1);
|
InFlag = SDOperand(ResNode, 1);
|
||||||
SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, 0, Chain.Val,
|
ReplaceUses(SDOperand(N.Val, 0), Chain);
|
||||||
Chain.ResNo);
|
ReplaceUses(SDOperand(N.Val, 1), InFlag);
|
||||||
SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, 1, InFlag.Val,
|
|
||||||
InFlag.ResNo);
|
|
||||||
Result = SDOperand(ResNode, N.ResNo);
|
Result = SDOperand(ResNode, N.ResNo);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@@ -25,6 +25,7 @@
|
|||||||
#include "llvm/Target/TargetLowering.h"
|
#include "llvm/Target/TargetLowering.h"
|
||||||
#include "llvm/Support/Debug.h"
|
#include "llvm/Support/Debug.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <queue>
|
||||||
#include <set>
|
#include <set>
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
@@ -1001,9 +1002,6 @@ void SparcDAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) {
|
|||||||
|
|
||||||
// Select target instructions for the DAG.
|
// Select target instructions for the DAG.
|
||||||
DAG.setRoot(SelectRoot(DAG.getRoot()));
|
DAG.setRoot(SelectRoot(DAG.getRoot()));
|
||||||
CodeGenMap.clear();
|
|
||||||
HandleMap.clear();
|
|
||||||
ReplaceMap.clear();
|
|
||||||
DAG.RemoveDeadNodes();
|
DAG.RemoveDeadNodes();
|
||||||
|
|
||||||
// Emit machine code to BB.
|
// Emit machine code to BB.
|
||||||
@@ -1083,21 +1081,14 @@ void SparcDAGToDAGISel::Select(SDOperand &Result, SDOperand Op) {
|
|||||||
return; // Already selected.
|
return; // Already selected.
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this has already been converted, use it.
|
|
||||||
std::map<SDOperand, SDOperand>::iterator CGMI = CodeGenMap.find(Op);
|
|
||||||
if (CGMI != CodeGenMap.end()) {
|
|
||||||
Result = CGMI->second;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (N->getOpcode()) {
|
switch (N->getOpcode()) {
|
||||||
default: break;
|
default: break;
|
||||||
case ISD::SDIV:
|
case ISD::SDIV:
|
||||||
case ISD::UDIV: {
|
case ISD::UDIV: {
|
||||||
// FIXME: should use a custom expander to expose the SRA to the dag.
|
// FIXME: should use a custom expander to expose the SRA to the dag.
|
||||||
SDOperand DivLHS, DivRHS;
|
SDOperand DivLHS, DivRHS;
|
||||||
Select(DivLHS, N->getOperand(0));
|
AddToQueue(DivLHS, N->getOperand(0));
|
||||||
Select(DivRHS, N->getOperand(1));
|
AddToQueue(DivRHS, N->getOperand(1));
|
||||||
|
|
||||||
// Set the Y register to the high-part.
|
// Set the Y register to the high-part.
|
||||||
SDOperand TopPart;
|
SDOperand TopPart;
|
||||||
@@ -1119,8 +1110,8 @@ void SparcDAGToDAGISel::Select(SDOperand &Result, SDOperand Op) {
|
|||||||
case ISD::MULHS: {
|
case ISD::MULHS: {
|
||||||
// FIXME: Handle mul by immediate.
|
// FIXME: Handle mul by immediate.
|
||||||
SDOperand MulLHS, MulRHS;
|
SDOperand MulLHS, MulRHS;
|
||||||
Select(MulLHS, N->getOperand(0));
|
AddToQueue(MulLHS, N->getOperand(0));
|
||||||
Select(MulRHS, N->getOperand(1));
|
AddToQueue(MulRHS, N->getOperand(1));
|
||||||
unsigned Opcode = N->getOpcode() == ISD::MULHU ? SP::UMULrr : SP::SMULrr;
|
unsigned Opcode = N->getOpcode() == ISD::MULHU ? SP::UMULrr : SP::SMULrr;
|
||||||
SDNode *Mul = CurDAG->getTargetNode(Opcode, MVT::i32, MVT::Flag,
|
SDNode *Mul = CurDAG->getTargetNode(Opcode, MVT::i32, MVT::Flag,
|
||||||
MulLHS, MulRHS);
|
MulLHS, MulRHS);
|
||||||
|
@@ -12,7 +12,7 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#define DEBUG_TYPE "isel"
|
#define DEBUG_TYPE "x86-isel"
|
||||||
#include "X86.h"
|
#include "X86.h"
|
||||||
#include "X86InstrBuilder.h"
|
#include "X86InstrBuilder.h"
|
||||||
#include "X86ISelLowering.h"
|
#include "X86ISelLowering.h"
|
||||||
@@ -35,6 +35,7 @@
|
|||||||
#include "llvm/ADT/Statistic.h"
|
#include "llvm/ADT/Statistic.h"
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <queue>
|
||||||
#include <set>
|
#include <set>
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
@@ -99,7 +100,7 @@ namespace {
|
|||||||
: SelectionDAGISel(X86Lowering),
|
: SelectionDAGISel(X86Lowering),
|
||||||
X86Lowering(*TM.getTargetLowering()),
|
X86Lowering(*TM.getTargetLowering()),
|
||||||
Subtarget(&TM.getSubtarget<X86Subtarget>()),
|
Subtarget(&TM.getSubtarget<X86Subtarget>()),
|
||||||
DAGSize(0), ReachabilityMatrix(NULL), ReachMatrixRange(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
|
||||||
@@ -123,7 +124,7 @@ namespace {
|
|||||||
#include "X86GenDAGISel.inc"
|
#include "X86GenDAGISel.inc"
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void DetermineReachability(SDNode *f, SDNode *t);
|
void DetermineReachability();
|
||||||
|
|
||||||
void Select(SDOperand &Result, SDOperand N);
|
void Select(SDOperand &Result, SDOperand N);
|
||||||
|
|
||||||
@@ -135,6 +136,18 @@ namespace {
|
|||||||
bool TryFoldLoad(SDOperand P, SDOperand N,
|
bool TryFoldLoad(SDOperand P, SDOperand N,
|
||||||
SDOperand &Base, SDOperand &Scale,
|
SDOperand &Base, SDOperand &Scale,
|
||||||
SDOperand &Index, SDOperand &Disp);
|
SDOperand &Index, SDOperand &Disp);
|
||||||
|
|
||||||
|
virtual void SelectRootInit() {
|
||||||
|
DAGSize = CurDAG->AssignTopologicalOrder(TopOrder);
|
||||||
|
unsigned NumBytes = (DAGSize + 7) / 8;
|
||||||
|
UnfoldableSet = new unsigned char[NumBytes];
|
||||||
|
memset(UnfoldableSet, 0, NumBytes);
|
||||||
|
unsigned RMSize = (DAGSize * DAGSize + 7) / 8;
|
||||||
|
ReachabilityMatrix = new unsigned char[RMSize];
|
||||||
|
memset(ReachabilityMatrix, 0, RMSize);
|
||||||
|
DetermineReachability();
|
||||||
|
}
|
||||||
|
|
||||||
/// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
|
/// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
|
||||||
/// inline asm expressions.
|
/// inline asm expressions.
|
||||||
virtual bool SelectInlineAsmMemoryOperand(const SDOperand &Op,
|
virtual bool SelectInlineAsmMemoryOperand(const SDOperand &Op,
|
||||||
@@ -179,22 +192,10 @@ namespace {
|
|||||||
/// base register. Return the virtual register that holds this value.
|
/// base register. Return the virtual register that holds this value.
|
||||||
SDOperand getGlobalBaseReg();
|
SDOperand getGlobalBaseReg();
|
||||||
|
|
||||||
/// DAGSize - Number of nodes in the DAG.
|
|
||||||
///
|
|
||||||
unsigned DAGSize;
|
|
||||||
|
|
||||||
/// TopOrder - Topological ordering of all nodes in the DAG.
|
|
||||||
///
|
|
||||||
std::vector<SDNode*> TopOrder;
|
|
||||||
|
|
||||||
/// ReachabilityMatrix - A N x N matrix representing all pairs reachability
|
/// ReachabilityMatrix - A N x N matrix representing all pairs reachability
|
||||||
/// information. One bit per potential edge.
|
/// information. One bit per potential edge.
|
||||||
unsigned char *ReachabilityMatrix;
|
unsigned char *ReachabilityMatrix;
|
||||||
|
|
||||||
/// ReachMatrixRange - The range of reachability information available for
|
|
||||||
/// the particular source node.
|
|
||||||
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 / 8] |= 1 << (Idx % 8);
|
||||||
@@ -243,7 +244,6 @@ bool X86DAGToDAGISel::CanBeFoldedBy(SDNode *N, SDNode *U) {
|
|||||||
// / [X]
|
// / [X]
|
||||||
// | ^
|
// | ^
|
||||||
// [U]--------|
|
// [U]--------|
|
||||||
DetermineReachability(U, N);
|
|
||||||
assert(isReachable(U, N) && "Attempting to fold a non-operand node?");
|
assert(isReachable(U, N) && "Attempting to fold a non-operand node?");
|
||||||
for (SDNode::op_iterator I = U->op_begin(), E = U->op_end(); I != E; ++I) {
|
for (SDNode::op_iterator I = U->op_begin(), E = U->op_end(); I != E; ++I) {
|
||||||
SDNode *P = I->Val;
|
SDNode *P = I->Val;
|
||||||
@@ -255,23 +255,15 @@ bool X86DAGToDAGISel::CanBeFoldedBy(SDNode *N, SDNode *U) {
|
|||||||
|
|
||||||
/// DetermineReachability - Determine reachability between all pairs of nodes
|
/// DetermineReachability - Determine reachability 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() {
|
||||||
unsigned Orderf = f->getNodeId();
|
for (unsigned i = 0; i < DAGSize; ++i) {
|
||||||
unsigned Ordert = t->getNodeId();
|
|
||||||
unsigned Range = ReachMatrixRange[Orderf];
|
|
||||||
if (Range >= Ordert)
|
|
||||||
return;
|
|
||||||
if (Range < Orderf)
|
|
||||||
Range = Orderf;
|
|
||||||
|
|
||||||
for (unsigned i = Range; i < Ordert; ++i) {
|
|
||||||
SDNode *N = TopOrder[i];
|
SDNode *N = TopOrder[i];
|
||||||
setReachable(N, N);
|
setReachable(N, N);
|
||||||
// If N is a leaf node, there is nothing more to do.
|
// If N is a leaf node, there is nothing more to do.
|
||||||
if (N->getNumOperands() == 0)
|
if (N->getNumOperands() == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (unsigned i2 = Range; ; ++i2) {
|
for (unsigned i2 = 0; ; ++i2) {
|
||||||
SDNode *M = TopOrder[i2];
|
SDNode *M = TopOrder[i2];
|
||||||
if (isReachable(M, N)) {
|
if (isReachable(M, N)) {
|
||||||
// Update reachability from M to N's operands.
|
// Update reachability from M to N's operands.
|
||||||
@@ -284,8 +276,6 @@ void X86DAGToDAGISel::DetermineReachability(SDNode *f, SDNode *t) {
|
|||||||
if (M == N) break;
|
if (M == N) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ReachMatrixRange[Orderf] = Ordert;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// InstructionSelectBasicBlock - This callback is invoked by SelectionDAGISel
|
/// InstructionSelectBasicBlock - This callback is invoked by SelectionDAGISel
|
||||||
@@ -294,16 +284,6 @@ void X86DAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) {
|
|||||||
DEBUG(BB->dump());
|
DEBUG(BB->dump());
|
||||||
MachineFunction::iterator FirstMBB = BB;
|
MachineFunction::iterator FirstMBB = BB;
|
||||||
|
|
||||||
DAGSize = DAG.AssignTopologicalOrder(TopOrder);
|
|
||||||
unsigned RMSize = (DAGSize * DAGSize + 7) / 8;
|
|
||||||
ReachabilityMatrix = new unsigned char[RMSize];
|
|
||||||
memset(ReachabilityMatrix, 0, RMSize);
|
|
||||||
ReachMatrixRange = new unsigned[DAGSize];
|
|
||||||
memset(ReachMatrixRange, 0, DAGSize * sizeof(unsigned));
|
|
||||||
unsigned NumBytes = (DAGSize + 7) / 8;
|
|
||||||
UnfoldableSet = new unsigned char[NumBytes];
|
|
||||||
memset(UnfoldableSet, 0, NumBytes);
|
|
||||||
|
|
||||||
// Codegen the basic block.
|
// Codegen the basic block.
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
DEBUG(std::cerr << "===== Instruction selection begins:\n");
|
DEBUG(std::cerr << "===== Instruction selection begins:\n");
|
||||||
@@ -315,15 +295,9 @@ void X86DAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
delete[] ReachabilityMatrix;
|
delete[] ReachabilityMatrix;
|
||||||
delete[] ReachMatrixRange;
|
|
||||||
delete[] UnfoldableSet;
|
delete[] UnfoldableSet;
|
||||||
ReachabilityMatrix = NULL;
|
ReachabilityMatrix = NULL;
|
||||||
ReachMatrixRange = NULL;
|
|
||||||
UnfoldableSet = NULL;
|
UnfoldableSet = NULL;
|
||||||
TopOrder.clear();
|
|
||||||
CodeGenMap.clear();
|
|
||||||
HandleMap.clear();
|
|
||||||
ReplaceMap.clear();
|
|
||||||
DAG.RemoveDeadNodes();
|
DAG.RemoveDeadNodes();
|
||||||
|
|
||||||
// Emit machine code to BB.
|
// Emit machine code to BB.
|
||||||
@@ -414,13 +388,8 @@ void X86DAGToDAGISel::EmitFunctionEntryCode(Function &Fn, MachineFunction &MF) {
|
|||||||
/// addressing mode
|
/// addressing mode
|
||||||
bool X86DAGToDAGISel::MatchAddress(SDOperand N, X86ISelAddressMode &AM,
|
bool X86DAGToDAGISel::MatchAddress(SDOperand N, X86ISelAddressMode &AM,
|
||||||
bool isRoot) {
|
bool isRoot) {
|
||||||
bool Available = false;
|
int id = N.Val->getNodeId();
|
||||||
// If N has already been selected, reuse the result unless in some very
|
bool Available = isSelected(id);
|
||||||
// specific cases.
|
|
||||||
std::map<SDOperand, SDOperand>::iterator CGMI= CodeGenMap.find(N.getValue(0));
|
|
||||||
if (CGMI != CodeGenMap.end()) {
|
|
||||||
Available = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (N.getOpcode()) {
|
switch (N.getOpcode()) {
|
||||||
default: break;
|
default: break;
|
||||||
@@ -664,7 +633,6 @@ bool X86DAGToDAGISel::TryFoldLoad(SDOperand P, SDOperand N,
|
|||||||
SDOperand &Index, SDOperand &Disp) {
|
SDOperand &Index, SDOperand &Disp) {
|
||||||
if (N.getOpcode() == ISD::LOAD &&
|
if (N.getOpcode() == ISD::LOAD &&
|
||||||
N.hasOneUse() &&
|
N.hasOneUse() &&
|
||||||
!CodeGenMap.count(N.getValue(0)) &&
|
|
||||||
!CanBeFoldedBy(N.Val, P.Val))
|
!CanBeFoldedBy(N.Val, P.Val))
|
||||||
return SelectAddr(N.getOperand(1), Base, Scale, Index, Disp);
|
return SelectAddr(N.getOperand(1), Base, Scale, Index, Disp);
|
||||||
return false;
|
return false;
|
||||||
@@ -727,23 +695,11 @@ void X86DAGToDAGISel::Select(SDOperand &Result, SDOperand N) {
|
|||||||
return; // Already selected.
|
return; // Already selected.
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<SDOperand, SDOperand>::iterator CGMI = CodeGenMap.find(N);
|
|
||||||
if (CGMI != CodeGenMap.end()) {
|
|
||||||
Result = CGMI->second;
|
|
||||||
#ifndef NDEBUG
|
|
||||||
DEBUG(std::cerr << std::string(Indent-2, ' '));
|
|
||||||
DEBUG(std::cerr << "== ");
|
|
||||||
DEBUG(Result.Val->dump(CurDAG));
|
|
||||||
DEBUG(std::cerr << "\n");
|
|
||||||
Indent -= 2;
|
|
||||||
#endif
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (Opcode) {
|
switch (Opcode) {
|
||||||
default: break;
|
default: break;
|
||||||
case X86ISD::GlobalBaseReg:
|
case X86ISD::GlobalBaseReg:
|
||||||
Result = getGlobalBaseReg();
|
Result = getGlobalBaseReg();
|
||||||
|
ReplaceUses(N, Result);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case ISD::ADD: {
|
case ISD::ADD: {
|
||||||
@@ -774,7 +730,8 @@ void X86DAGToDAGISel::Select(SDOperand &Result, SDOperand N) {
|
|||||||
Result = CurDAG->SelectNodeTo(N.Val, X86::MOV32ri, MVT::i32, C);
|
Result = CurDAG->SelectNodeTo(N.Val, X86::MOV32ri, MVT::i32, C);
|
||||||
} else {
|
} else {
|
||||||
SDNode *ResNode = CurDAG->getTargetNode(X86::MOV32ri, MVT::i32, C);
|
SDNode *ResNode = CurDAG->getTargetNode(X86::MOV32ri, MVT::i32, C);
|
||||||
Result = CodeGenMap[N] = SDOperand(ResNode, 0);
|
Result = SDOperand(ResNode, 0);
|
||||||
|
ReplaceUses(N, Result);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -826,42 +783,40 @@ void X86DAGToDAGISel::Select(SDOperand &Result, SDOperand N) {
|
|||||||
|
|
||||||
SDOperand Chain;
|
SDOperand Chain;
|
||||||
if (foldedLoad)
|
if (foldedLoad)
|
||||||
Select(Chain, N1.getOperand(0));
|
AddToQueue(Chain, N1.getOperand(0));
|
||||||
else
|
else
|
||||||
Chain = CurDAG->getEntryNode();
|
Chain = CurDAG->getEntryNode();
|
||||||
|
|
||||||
SDOperand InFlag(0, 0);
|
SDOperand InFlag(0, 0);
|
||||||
Select(N0, N0);
|
AddToQueue(N0, N0);
|
||||||
Chain = CurDAG->getCopyToReg(Chain, CurDAG->getRegister(LoReg, NVT),
|
Chain = CurDAG->getCopyToReg(Chain, CurDAG->getRegister(LoReg, NVT),
|
||||||
N0, InFlag);
|
N0, InFlag);
|
||||||
InFlag = Chain.getValue(1);
|
InFlag = Chain.getValue(1);
|
||||||
|
|
||||||
if (foldedLoad) {
|
if (foldedLoad) {
|
||||||
Select(Tmp0, Tmp0);
|
AddToQueue(Tmp0, Tmp0);
|
||||||
Select(Tmp1, Tmp1);
|
AddToQueue(Tmp1, Tmp1);
|
||||||
Select(Tmp2, Tmp2);
|
AddToQueue(Tmp2, Tmp2);
|
||||||
Select(Tmp3, Tmp3);
|
AddToQueue(Tmp3, Tmp3);
|
||||||
SDNode *CNode =
|
SDNode *CNode =
|
||||||
CurDAG->getTargetNode(MOpc, MVT::Other, MVT::Flag, Tmp0, Tmp1,
|
CurDAG->getTargetNode(MOpc, MVT::Other, MVT::Flag, Tmp0, Tmp1,
|
||||||
Tmp2, Tmp3, Chain, InFlag);
|
Tmp2, Tmp3, Chain, InFlag);
|
||||||
Chain = SDOperand(CNode, 0);
|
Chain = SDOperand(CNode, 0);
|
||||||
InFlag = SDOperand(CNode, 1);
|
InFlag = SDOperand(CNode, 1);
|
||||||
} else {
|
} else {
|
||||||
Select(N1, N1);
|
AddToQueue(N1, N1);
|
||||||
InFlag =
|
InFlag =
|
||||||
SDOperand(CurDAG->getTargetNode(Opc, MVT::Flag, N1, InFlag), 0);
|
SDOperand(CurDAG->getTargetNode(Opc, MVT::Flag, N1, InFlag), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result = CurDAG->getCopyFromReg(Chain, HiReg, NVT, InFlag);
|
Result = CurDAG->getCopyFromReg(Chain, HiReg, NVT, InFlag);
|
||||||
CodeGenMap[N.getValue(0)] = Result;
|
ReplaceUses(N.getValue(0), Result);
|
||||||
if (foldedLoad) {
|
if (foldedLoad)
|
||||||
CodeGenMap[N1.getValue(1)] = Result.getValue(1);
|
ReplaceUses(N1.getValue(1), Result.getValue(1));
|
||||||
AddHandleReplacement(N1.Val, 1, Result.Val, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
DEBUG(std::cerr << std::string(Indent-2, ' '));
|
DEBUG(std::cerr << std::string(Indent-2, ' '));
|
||||||
DEBUG(std::cerr << "== ");
|
DEBUG(std::cerr << "=> ");
|
||||||
DEBUG(Result.Val->dump(CurDAG));
|
DEBUG(Result.Val->dump(CurDAG));
|
||||||
DEBUG(std::cerr << "\n");
|
DEBUG(std::cerr << "\n");
|
||||||
Indent -= 2;
|
Indent -= 2;
|
||||||
@@ -919,12 +874,12 @@ void X86DAGToDAGISel::Select(SDOperand &Result, SDOperand N) {
|
|||||||
foldedLoad = TryFoldLoad(N, N1, Tmp0, Tmp1, Tmp2, Tmp3);
|
foldedLoad = TryFoldLoad(N, N1, Tmp0, Tmp1, Tmp2, Tmp3);
|
||||||
SDOperand Chain;
|
SDOperand Chain;
|
||||||
if (foldedLoad)
|
if (foldedLoad)
|
||||||
Select(Chain, N1.getOperand(0));
|
AddToQueue(Chain, N1.getOperand(0));
|
||||||
else
|
else
|
||||||
Chain = CurDAG->getEntryNode();
|
Chain = CurDAG->getEntryNode();
|
||||||
|
|
||||||
SDOperand InFlag(0, 0);
|
SDOperand InFlag(0, 0);
|
||||||
Select(N0, N0);
|
AddToQueue(N0, N0);
|
||||||
Chain = CurDAG->getCopyToReg(Chain, CurDAG->getRegister(LoReg, NVT),
|
Chain = CurDAG->getCopyToReg(Chain, CurDAG->getRegister(LoReg, NVT),
|
||||||
N0, InFlag);
|
N0, InFlag);
|
||||||
InFlag = Chain.getValue(1);
|
InFlag = Chain.getValue(1);
|
||||||
@@ -942,32 +897,30 @@ void X86DAGToDAGISel::Select(SDOperand &Result, SDOperand N) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (foldedLoad) {
|
if (foldedLoad) {
|
||||||
Select(Tmp0, Tmp0);
|
AddToQueue(Tmp0, Tmp0);
|
||||||
Select(Tmp1, Tmp1);
|
AddToQueue(Tmp1, Tmp1);
|
||||||
Select(Tmp2, Tmp2);
|
AddToQueue(Tmp2, Tmp2);
|
||||||
Select(Tmp3, Tmp3);
|
AddToQueue(Tmp3, Tmp3);
|
||||||
SDNode *CNode =
|
SDNode *CNode =
|
||||||
CurDAG->getTargetNode(MOpc, MVT::Other, MVT::Flag, Tmp0, Tmp1,
|
CurDAG->getTargetNode(MOpc, MVT::Other, MVT::Flag, Tmp0, Tmp1,
|
||||||
Tmp2, Tmp3, Chain, InFlag);
|
Tmp2, Tmp3, Chain, InFlag);
|
||||||
Chain = SDOperand(CNode, 0);
|
Chain = SDOperand(CNode, 0);
|
||||||
InFlag = SDOperand(CNode, 1);
|
InFlag = SDOperand(CNode, 1);
|
||||||
} else {
|
} else {
|
||||||
Select(N1, N1);
|
AddToQueue(N1, N1);
|
||||||
InFlag =
|
InFlag =
|
||||||
SDOperand(CurDAG->getTargetNode(Opc, MVT::Flag, N1, InFlag), 0);
|
SDOperand(CurDAG->getTargetNode(Opc, MVT::Flag, N1, InFlag), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result = CurDAG->getCopyFromReg(Chain, isDiv ? LoReg : HiReg,
|
Result = CurDAG->getCopyFromReg(Chain, isDiv ? LoReg : HiReg,
|
||||||
NVT, InFlag);
|
NVT, InFlag);
|
||||||
CodeGenMap[N.getValue(0)] = Result;
|
ReplaceUses(N.getValue(0), Result);
|
||||||
if (foldedLoad) {
|
if (foldedLoad)
|
||||||
CodeGenMap[N1.getValue(1)] = Result.getValue(1);
|
ReplaceUses(N1.getValue(1), Result.getValue(1));
|
||||||
AddHandleReplacement(N1.Val, 1, Result.Val, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
DEBUG(std::cerr << std::string(Indent-2, ' '));
|
DEBUG(std::cerr << std::string(Indent-2, ' '));
|
||||||
DEBUG(std::cerr << "== ");
|
DEBUG(std::cerr << "=> ");
|
||||||
DEBUG(Result.Val->dump(CurDAG));
|
DEBUG(Result.Val->dump(CurDAG));
|
||||||
DEBUG(std::cerr << "\n");
|
DEBUG(std::cerr << "\n");
|
||||||
Indent -= 2;
|
Indent -= 2;
|
||||||
@@ -994,14 +947,14 @@ void X86DAGToDAGISel::Select(SDOperand &Result, SDOperand N) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SDOperand Tmp0, Tmp1;
|
SDOperand Tmp0, Tmp1;
|
||||||
Select(Tmp0, Node->getOperand(0));
|
AddToQueue(Tmp0, Node->getOperand(0));
|
||||||
Tmp1 = SDOperand(CurDAG->getTargetNode(Opc, VT, Tmp0), 0);
|
Tmp1 = SDOperand(CurDAG->getTargetNode(Opc, VT, Tmp0), 0);
|
||||||
Result = CodeGenMap[N] =
|
Result = SDOperand(CurDAG->getTargetNode(Opc2, NVT, Tmp1), 0);
|
||||||
SDOperand(CurDAG->getTargetNode(Opc2, NVT, Tmp1), 0);
|
ReplaceUses(N, Result);
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
DEBUG(std::cerr << std::string(Indent-2, ' '));
|
DEBUG(std::cerr << std::string(Indent-2, ' '));
|
||||||
DEBUG(std::cerr << "== ");
|
DEBUG(std::cerr << "=> ");
|
||||||
DEBUG(Result.Val->dump(CurDAG));
|
DEBUG(Result.Val->dump(CurDAG));
|
||||||
DEBUG(std::cerr << "\n");
|
DEBUG(std::cerr << "\n");
|
||||||
Indent -= 2;
|
Indent -= 2;
|
||||||
@@ -1038,10 +991,10 @@ SelectInlineAsmMemoryOperand(const SDOperand &Op, char ConstraintCode,
|
|||||||
}
|
}
|
||||||
|
|
||||||
OutOps.resize(4);
|
OutOps.resize(4);
|
||||||
Select(OutOps[0], Op0);
|
AddToQueue(OutOps[0], Op0);
|
||||||
Select(OutOps[1], Op1);
|
AddToQueue(OutOps[1], Op1);
|
||||||
Select(OutOps[2], Op2);
|
AddToQueue(OutOps[2], Op2);
|
||||||
Select(OutOps[3], Op3);
|
AddToQueue(OutOps[3], Op3);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user