summaryrefslogtreecommitdiff
path: root/lib/Target/X86/X86ISelDAGToDAG.cpp
diff options
context:
space:
mode:
authorDan Gohman <gohman@apple.com>2008-08-23 02:25:05 +0000
committerDan Gohman <gohman@apple.com>2008-08-23 02:25:05 +0000
commitf350b277f32d7d47f86c0e54f4aec4d470500618 (patch)
tree7fd5f490b6220846cd2de9eb7a8f48c0d29ea9c5 /lib/Target/X86/X86ISelDAGToDAG.cpp
parent6679906d9724868bf2198e04952ba42f31d7b7fe (diff)
downloadllvm-f350b277f32d7d47f86c0e54f4aec4d470500618.tar.gz
llvm-f350b277f32d7d47f86c0e54f4aec4d470500618.tar.bz2
llvm-f350b277f32d7d47f86c0e54f4aec4d470500618.tar.xz
Move the point at which FastISel taps into the SelectionDAGISel
process up to a higher level. This allows FastISel to leverage more of SelectionDAGISel's infastructure, such as updating Machine PHI nodes. Also, implement transitioning from SDISel back to FastISel in the middle of a block, so it's now possible to go back and forth. This allows FastISel to hand individual CallInsts and other complicated things off to SDISel to handle, while handling the rest of the block itself. To help support this, reorganize the SelectionDAG class so that it is allocated once and reused throughout a function, instead of being completely reallocated for each block. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@55219 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/X86/X86ISelDAGToDAG.cpp')
-rw-r--r--lib/Target/X86/X86ISelDAGToDAG.cpp58
1 files changed, 29 insertions, 29 deletions
diff --git a/lib/Target/X86/X86ISelDAGToDAG.cpp b/lib/Target/X86/X86ISelDAGToDAG.cpp
index 21837d53d4..29986e50d6 100644
--- a/lib/Target/X86/X86ISelDAGToDAG.cpp
+++ b/lib/Target/X86/X86ISelDAGToDAG.cpp
@@ -147,7 +147,7 @@ namespace {
/// InstructionSelect - This callback is invoked by
/// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
- virtual void InstructionSelect(SelectionDAG &DAG);
+ virtual void InstructionSelect();
/// InstructionSelectPostProcessing - Post processing of selected and
/// scheduled basic blocks.
@@ -178,15 +178,14 @@ namespace {
bool TryFoldLoad(SDValue P, SDValue N,
SDValue &Base, SDValue &Scale,
SDValue &Index, SDValue &Disp);
- void PreprocessForRMW(SelectionDAG &DAG);
- void PreprocessForFPConvert(SelectionDAG &DAG);
+ void PreprocessForRMW();
+ void PreprocessForFPConvert();
/// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
/// inline asm expressions.
virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op,
char ConstraintCode,
- std::vector<SDValue> &OutOps,
- SelectionDAG &DAG);
+ std::vector<SDValue> &OutOps);
void EmitSpecialCodeForMain(MachineBasicBlock *BB, MachineFrameInfo *MFI);
@@ -372,7 +371,7 @@ bool X86DAGToDAGISel::CanBeFoldedBy(SDNode *N, SDNode *U, SDNode *Root) const {
/// MoveBelowTokenFactor - Replace TokenFactor operand with load's chain operand
/// and move load below the TokenFactor. Replace store's chain operand with
/// load's chain result.
-static void MoveBelowTokenFactor(SelectionDAG &DAG, SDValue Load,
+static void MoveBelowTokenFactor(SelectionDAG *CurDAG, SDValue Load,
SDValue Store, SDValue TF) {
std::vector<SDValue> Ops;
for (unsigned i = 0, e = TF.Val->getNumOperands(); i != e; ++i)
@@ -380,10 +379,10 @@ static void MoveBelowTokenFactor(SelectionDAG &DAG, SDValue Load,
Ops.push_back(Load.Val->getOperand(0));
else
Ops.push_back(TF.Val->getOperand(i));
- DAG.UpdateNodeOperands(TF, &Ops[0], Ops.size());
- DAG.UpdateNodeOperands(Load, TF, Load.getOperand(1), Load.getOperand(2));
- DAG.UpdateNodeOperands(Store, Load.getValue(1), Store.getOperand(1),
- Store.getOperand(2), Store.getOperand(3));
+ CurDAG->UpdateNodeOperands(TF, &Ops[0], Ops.size());
+ CurDAG->UpdateNodeOperands(Load, TF, Load.getOperand(1), Load.getOperand(2));
+ CurDAG->UpdateNodeOperands(Store, Load.getValue(1), Store.getOperand(1),
+ Store.getOperand(2), Store.getOperand(3));
}
/// isRMWLoad - Return true if N is a load that's part of RMW sub-DAG.
@@ -452,9 +451,9 @@ static bool isRMWLoad(SDValue N, SDValue Chain, SDValue Address,
/// \ /
/// \ /
/// [Store]
-void X86DAGToDAGISel::PreprocessForRMW(SelectionDAG &DAG) {
- for (SelectionDAG::allnodes_iterator I = DAG.allnodes_begin(),
- E = DAG.allnodes_end(); I != E; ++I) {
+void X86DAGToDAGISel::PreprocessForRMW() {
+ for (SelectionDAG::allnodes_iterator I = CurDAG->allnodes_begin(),
+ E = CurDAG->allnodes_end(); I != E; ++I) {
if (!ISD::isNON_TRUNCStore(I))
continue;
SDValue Chain = I->getOperand(0);
@@ -504,7 +503,7 @@ void X86DAGToDAGISel::PreprocessForRMW(SelectionDAG &DAG) {
}
if (RModW) {
- MoveBelowTokenFactor(DAG, Load, SDValue(I, 0), Chain);
+ MoveBelowTokenFactor(CurDAG, Load, SDValue(I, 0), Chain);
++NumLoadMoved;
}
}
@@ -519,9 +518,9 @@ void X86DAGToDAGISel::PreprocessForRMW(SelectionDAG &DAG) {
/// hack on these between the call expansion and the node legalization. As such
/// this pass basically does "really late" legalization of these inline with the
/// X86 isel pass.
-void X86DAGToDAGISel::PreprocessForFPConvert(SelectionDAG &DAG) {
- for (SelectionDAG::allnodes_iterator I = DAG.allnodes_begin(),
- E = DAG.allnodes_end(); I != E; ) {
+void X86DAGToDAGISel::PreprocessForFPConvert() {
+ for (SelectionDAG::allnodes_iterator I = CurDAG->allnodes_begin(),
+ E = CurDAG->allnodes_end(); I != E; ) {
SDNode *N = I++; // Preincrement iterator to avoid invalidation issues.
if (N->getOpcode() != ISD::FP_ROUND && N->getOpcode() != ISD::FP_EXTEND)
continue;
@@ -553,39 +552,40 @@ void X86DAGToDAGISel::PreprocessForFPConvert(SelectionDAG &DAG) {
else
MemVT = SrcIsSSE ? SrcVT : DstVT;
- SDValue MemTmp = DAG.CreateStackTemporary(MemVT);
+ SDValue MemTmp = CurDAG->CreateStackTemporary(MemVT);
// FIXME: optimize the case where the src/dest is a load or store?
- SDValue Store = DAG.getTruncStore(DAG.getEntryNode(), N->getOperand(0),
- MemTmp, NULL, 0, MemVT);
- SDValue Result = DAG.getExtLoad(ISD::EXTLOAD, DstVT, Store, MemTmp,
- NULL, 0, MemVT);
+ SDValue Store = CurDAG->getTruncStore(CurDAG->getEntryNode(),
+ N->getOperand(0),
+ MemTmp, NULL, 0, MemVT);
+ SDValue Result = CurDAG->getExtLoad(ISD::EXTLOAD, DstVT, Store, MemTmp,
+ NULL, 0, MemVT);
// We're about to replace all uses of the FP_ROUND/FP_EXTEND with the
// extload we created. This will cause general havok on the dag because
// anything below the conversion could be folded into other existing nodes.
// To avoid invalidating 'I', back it up to the convert node.
--I;
- DAG.ReplaceAllUsesOfValueWith(SDValue(N, 0), Result);
+ CurDAG->ReplaceAllUsesOfValueWith(SDValue(N, 0), Result);
// Now that we did that, the node is dead. Increment the iterator to the
// next node to process, then delete N.
++I;
- DAG.DeleteNode(N);
+ CurDAG->DeleteNode(N);
}
}
/// InstructionSelectBasicBlock - This callback is invoked by SelectionDAGISel
/// when it has created a SelectionDAG for us to codegen.
-void X86DAGToDAGISel::InstructionSelect(SelectionDAG &DAG) {
+void X86DAGToDAGISel::InstructionSelect() {
CurBB = BB; // BB can change as result of isel.
DEBUG(BB->dump());
if (!Fast)
- PreprocessForRMW(DAG);
+ PreprocessForRMW();
// FIXME: This should only happen when not -fast.
- PreprocessForFPConvert(DAG);
+ PreprocessForFPConvert();
// Codegen the basic block.
#ifndef NDEBUG
@@ -597,7 +597,7 @@ void X86DAGToDAGISel::InstructionSelect(SelectionDAG &DAG) {
DOUT << "===== Instruction selection ends:\n";
#endif
- DAG.RemoveDeadNodes();
+ CurDAG->RemoveDeadNodes();
}
void X86DAGToDAGISel::InstructionSelectPostProcessing() {
@@ -1599,7 +1599,7 @@ SDNode *X86DAGToDAGISel::Select(SDValue N) {
bool X86DAGToDAGISel::
SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode,
- std::vector<SDValue> &OutOps, SelectionDAG &DAG){
+ std::vector<SDValue> &OutOps) {
SDValue Op0, Op1, Op2, Op3;
switch (ConstraintCode) {
case 'o': // offsetable ??