diff options
author | Dan Gohman <gohman@apple.com> | 2008-02-06 22:27:42 +0000 |
---|---|---|
committer | Dan Gohman <gohman@apple.com> | 2008-02-06 22:27:42 +0000 |
commit | 69de1932b350d7cdfc0ed1f4198d6f78c7822a02 (patch) | |
tree | 9509f355cd39a5d69988db1d878c213d0526011d | |
parent | b745e88bf0a6d7f51a336cd6158824e7383e8d24 (diff) |
Re-apply the memory operand changes, with a fix for the static
initializer problem, a minor tweak to the way the
DAGISelEmitter finds load/store nodes, and a renaming of the
new PseudoSourceValue objects.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@46827 91177308-0d34-0410-b5e6-96231b3b80d8
21 files changed, 595 insertions, 157 deletions
diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h index 7c0bed8479..8b0931ac61 100644 --- a/include/llvm/CodeGen/MachineInstr.h +++ b/include/llvm/CodeGen/MachineInstr.h @@ -17,6 +17,7 @@ #define LLVM_CODEGEN_MACHINEINSTR_H #include "llvm/CodeGen/MachineOperand.h" +#include "llvm/CodeGen/MemOperand.h" namespace llvm { @@ -35,6 +36,7 @@ class MachineInstr { // are determined at construction time). std::vector<MachineOperand> Operands; // the operands + std::vector<MemOperand> MemOperands; // information on memory references MachineInstr *Prev, *Next; // Links for MBB's intrusive list. MachineBasicBlock *Parent; // Pointer to the owning basic block. @@ -94,6 +96,18 @@ public: /// unsigned getNumExplicitOperands() const; + /// Access to memory operands of the instruction + unsigned getNumMemOperands() const { return MemOperands.size(); } + + const MemOperand& getMemOperand(unsigned i) const { + assert(i < getNumMemOperands() && "getMemOperand() out of range!"); + return MemOperands[i]; + } + MemOperand& getMemOperand(unsigned i) { + assert(i < getNumMemOperands() && "getMemOperand() out of range!"); + return MemOperands[i]; + } + /// isIdenticalTo - Return true if this instruction is identical to (same /// opcode and same operands as) the specified instruction. bool isIdenticalTo(const MachineInstr *Other) const { @@ -196,6 +210,12 @@ public: /// void RemoveOperand(unsigned i); + /// addMemOperand - Add a MemOperand to the machine instruction, referencing + /// arbitrary storage. + void addMemOperand(const MemOperand &MO) { + MemOperands.push_back(MO); + } + private: /// getRegInfo - If this instruction is embedded into a MachineFunction, /// return the MachineRegisterInfo object for the current function, otherwise diff --git a/include/llvm/CodeGen/MachineInstrBuilder.h b/include/llvm/CodeGen/MachineInstrBuilder.h index 97d6736ac0..51900603ac 100644 --- a/include/llvm/CodeGen/MachineInstrBuilder.h +++ b/include/llvm/CodeGen/MachineInstrBuilder.h @@ -83,6 +83,12 @@ public: MI->addOperand(MachineOperand::CreateES(FnName, 0)); return *this; } + + /// addMemOperand - Add a memory operand to the machine instruction. + const MachineInstrBuilder &addMemOperand(const MemOperand &MO) const { + MI->addMemOperand(MO); + return *this; + } }; /// BuildMI - Builder interface. Specify how to create the initial instruction diff --git a/include/llvm/CodeGen/MemOperand.h b/include/llvm/CodeGen/MemOperand.h index e69de29bb2..e9f05f3eed 100644 --- a/include/llvm/CodeGen/MemOperand.h +++ b/include/llvm/CodeGen/MemOperand.h @@ -0,0 +1,82 @@ +//===-- llvm/CodeGen/MemOperand.h - MemOperand class ------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains the declaration of the MemOperand class, which is a +// description of a memory reference. It is used to help track dependencies +// in the backend. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CODEGEN_MEMOPERAND_H +#define LLVM_CODEGEN_MEMOPERAND_H + +namespace llvm { + +class Value; + +//===----------------------------------------------------------------------===// +/// MemOperand - A description of a memory reference used in the backend. +/// Instead of holding a StoreInst or LoadInst, this class holds the address +/// Value of the reference along with a byte size and offset. This allows it +/// to describe lowered loads and stores. Also, the special PseudoSourceValue +/// objects can be used to represent loads and stores to memory locations +/// that aren't explicit in the regular LLVM IR. +/// +class MemOperand { + const Value *V; + unsigned int Flags; + int Offset; + int Size; + unsigned int Alignment; + +public: + /// Flags values. These may be or'd together. + enum MemOperandFlags { + /// The memory access reads data. + MOLoad = 1, + /// The memory access writes data. + MOStore = 2, + /// The memory access is volatile. + MOVolatile = 4 + }; + + /// MemOperand - Construct an MemOperand object with the specified + /// address Value, flags, offset, size, and alignment. + MemOperand(const Value *v, unsigned int f, int o, int s, unsigned int a) + : V(v), Flags(f), Offset(o), Size(s), Alignment(a) {} + + /// getValue - Return the base address of the memory access. + /// Special values are PseudoSourceValue::FPRel, PseudoSourceValue::SPRel, + /// and the other PseudoSourceValue members which indicate references to + /// frame/stack pointer relative references and other special references. + const Value *getValue() const { return V; } + + /// getFlags - Return the raw flags of the source value, \see MemOperandFlags. + unsigned int getFlags() const { return Flags; } + + /// getOffset - For normal values, this is a byte offset added to the base + /// address. For PseudoSourceValue::FPRel values, this is the FrameIndex + /// number. + int getOffset() const { return Offset; } + + /// getSize - Return the size in bytes of the memory reference. + int getSize() const { return Size; } + + /// getAlignment - Return the minimum known alignment in bytes of the + /// memory reference. + unsigned int getAlignment() const { return Alignment; } + + bool isLoad() const { return Flags & MOLoad; } + bool isStore() const { return Flags & MOStore; } + bool isVolatile() const { return Flags & MOVolatile; } +}; + +} // End llvm namespace + +#endif diff --git a/include/llvm/CodeGen/PseudoSourceValue.h b/include/llvm/CodeGen/PseudoSourceValue.h index e69de29bb2..3eaf475a57 100644 --- a/include/llvm/CodeGen/PseudoSourceValue.h +++ b/include/llvm/CodeGen/PseudoSourceValue.h @@ -0,0 +1,58 @@ +//===-- llvm/CodeGen/PseudoSourceValue.h ------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains the declaration of the PseudoSourceValue class. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CODEGEN_PSEUDOSOURCEVALUE_H +#define LLVM_CODEGEN_PSEUDOSOURCEVALUE_H + +#include "llvm/Value.h" + +namespace llvm { + /// PseudoSourceValue - Special value supplied for machine level alias + /// analysis. It indicates that the a memory access references the functions + /// stack frame (e.g., a spill slot), below the stack frame (e.g., argument + /// space), or constant pool. + class PseudoSourceValue : public Value { + public: + PseudoSourceValue(); + + virtual void print(std::ostream &OS) const; + + /// classof - Methods for support type inquiry through isa, cast, and + /// dyn_cast: + /// + static inline bool classof(const PseudoSourceValue *) { return true; } + static inline bool classof(const Value *V) { + return V->getValueID() == PseudoSourceValueVal; + } + + /// A pseudo source value referencing to the stack frame of a function, + /// e.g., a spill slot. + static const PseudoSourceValue &getFixedStack(); + + /// A source value referencing the area below the stack frame of a function, + /// e.g., the argument space. + static const PseudoSourceValue &getStack(); + + /// A source value referencing the global offset table (or something the + /// like). + static const PseudoSourceValue &getGOT(); + + /// A SV referencing the constant pool + static const PseudoSourceValue &getConstantPool(); + + /// A SV referencing the jump table + static const PseudoSourceValue &getJumpTable(); + }; +} // End llvm namespace + +#endif diff --git a/include/llvm/CodeGen/ScheduleDAG.h b/include/llvm/CodeGen/ScheduleDAG.h index 77d1a1cce4..fdd5700357 100644 --- a/include/llvm/CodeGen/ScheduleDAG.h +++ b/include/llvm/CodeGen/ScheduleDAG.h @@ -279,6 +279,7 @@ namespace llvm { if (isa<ConstantPoolSDNode>(Node)) return true; if (isa<JumpTableSDNode>(Node)) return true; if (isa<ExternalSymbolSDNode>(Node)) return true; + if (isa<MemOperandSDNode>(Node)) return true; return false; } @@ -312,11 +313,15 @@ namespace llvm { /// (which do not go into the machine instrs.) static unsigned CountResults(SDNode *Node); - /// CountOperands The inputs to target nodes have any actual inputs first, - /// followed by an optional chain operand, then flag operands. Compute the - /// number of actual operands that will go into the machine instr. + /// CountOperands - The inputs to target nodes have any actual inputs first, + /// followed by optional memory operands chain operand, then flag operands. + /// Compute the number of actual operands that will go into the machine + /// instr. static unsigned CountOperands(SDNode *Node); + /// CountMemOperands - Find the index of the last MemOperandSDNode + static unsigned CountMemOperands(SDNode *Node); + /// EmitNode - Generate machine code for an node and needed dependencies. /// VRBaseMap contains, for each already emitted node, the first virtual /// register number for the results of the node. @@ -357,6 +362,8 @@ namespace llvm { void AddOperand(MachineInstr *MI, SDOperand Op, unsigned IIOpNum, const TargetInstrDesc *II, DenseMap<SDOperand, unsigned> &VRBaseMap); + + void AddMemOperand(MachineInstr *MI, const MemOperand &MO); }; /// createBURRListDAGScheduler - This creates a bottom up register usage diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h index 2550d64c14..0585e3e5d1 100644 --- a/include/llvm/CodeGen/SelectionDAG.h +++ b/include/llvm/CodeGen/SelectionDAG.h @@ -376,8 +376,12 @@ public: SDOperand getIndexedStore(SDOperand OrigStoe, SDOperand Base, SDOperand Offset, ISD::MemIndexedMode AM); - // getSrcValue - construct a node to track a Value* through the backend - SDOperand getSrcValue(const Value* I, int offset = 0); + // getSrcValue - Construct a node to track a Value* through the backend. + SDOperand getSrcValue(const Value *v); + + // getMemOperand - Construct a node to track a memory reference + // through the backend. + SDOperand getMemOperand(const MemOperand &MO); /// UpdateNodeOperands - *Mutate* the specified node in-place to have the /// specified operands. If the resultant node already exists in the DAG, diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h index 0509076352..9cb58c9329 100644 --- a/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/include/llvm/CodeGen/SelectionDAGNodes.h @@ -25,6 +25,7 @@ #include "llvm/ADT/iterator" #include "llvm/ADT/APFloat.h" #include "llvm/CodeGen/ValueTypes.h" +#include "llvm/CodeGen/MemOperand.h" #include "llvm/Support/DataTypes.h" #include <cassert> @@ -542,11 +543,15 @@ namespace ISD { // pointer, and a SRCVALUE. VAEND, VASTART, - // SRCVALUE - This corresponds to a Value*, and is used to associate memory - // locations with their value. This allows one use alias analysis - // information in the backend. + // SRCVALUE - This is a node type that holds a Value* that is used to + // make reference to a value in the LLVM IR. SRCVALUE, + // MEMOPERAND - This is a node that contains a MemOperand which records + // information about a memory reference. This is used to make AliasAnalysis + // queries from the backend. + MEMOPERAND, + // PCMARKER - This corresponds to the pcmarker intrinsic. PCMARKER, @@ -1391,17 +1396,16 @@ public: class SrcValueSDNode : public SDNode { const Value *V; - int offset; virtual void ANCHOR(); // Out-of-line virtual method to give class a home. protected: friend class SelectionDAG; - SrcValueSDNode(const Value* v, int o) - : SDNode(ISD::SRCVALUE, getSDVTList(MVT::Other)), V(v), offset(o) { - } + /// Create a SrcValue for a general value. + explicit SrcValueSDNode(const Value *v) + : SDNode(ISD::SRCVALUE, getSDVTList(MVT::Other)), V(v) {} public: + /// getValue - return the contained Value. const Value *getValue() const { return V; } - int getOffset() const { return offset; } static bool classof(const SrcValueSDNode *) { return true; } static bool classof(const SDNode *N) { @@ -1410,6 +1414,29 @@ public: }; +/// MemOperandSDNode - An SDNode that holds a MemOperand. This is +/// used to represent a reference to memory after ISD::LOAD +/// and ISD::STORE have been lowered. +/// +class MemOperandSDNode : public SDNode { + virtual void ANCHOR(); // Out-of-line virtual method to give class a home. +protected: + friend class SelectionDAG; + /// Create a MemOperand node + explicit MemOperandSDNode(MemOperand mo) + : SDNode(ISD::MEMOPERAND, getSDVTList(MVT::Other)), MO(mo) {} + +public: + /// MO - The contained MemOperand. + const MemOperand MO; + + static bool classof(const MemOperandSDNode *) { return true; } + static bool classof(const SDNode *N) { + return N->getOpcode() == ISD::MEMOPERAND; + } +}; + + class RegisterSDNode : public SDNode { unsigned Reg; virtual void ANCHOR(); // Out-of-line virtual method to give class a home. @@ -1559,6 +1586,10 @@ public: /// isUnindexed - Return true if this is NOT a pre/post inc/dec load/store. bool isUnindexed() const { return AddrMode == ISD::UNINDEXED; } + /// getMemOperand - Return a MemOperand object describing the memory + /// reference performed by this load or store. + MemOperand getMemOperand() const; + static bool classof(const LSBaseSDNode *N) { return true; } static bool classof(const SDNode *N) { return N->getOpcode() == ISD::LOAD || diff --git a/include/llvm/Value.h b/include/llvm/Value.h index fc1cf48209..2654b18d3d 100644 --- a/include/llvm/Value.h +++ b/include/llvm/Value.h @@ -187,6 +187,7 @@ public: ConstantVectorVal, // This is an instance of ConstantVector ConstantPointerNullVal, // This is an instance of ConstantPointerNull InlineAsmVal, // This is an instance of InlineAsm + PseudoSourceValueVal, // This is an instance of PseudoSourceValue InstructionVal, // This is an instance of Instruction // Markers: diff --git a/lib/CodeGen/MachineInstr.cpp b/lib/CodeGen/MachineInstr.cpp index e1e2336b50..c455b024e3 100644 --- a/lib/CodeGen/MachineInstr.cpp +++ b/lib/CodeGen/MachineInstr.cpp @@ -15,6 +15,8 @@ #include "llvm/Value.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/CodeGen/PseudoSourceValue.h" +#include "llvm/CodeGen/SelectionDAGNodes.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetInstrDesc.h" @@ -292,6 +294,7 @@ MachineInstr::MachineInstr(const MachineInstr &MI) { TID = &MI.getDesc(); NumImplicitOps = MI.NumImplicitOps; Operands.reserve(MI.getNumOperands()); + MemOperands = MI.MemOperands; // Add operands for (unsigned i = 0; i != MI.getNumOperands(); ++i) { @@ -627,6 +630,34 @@ void MachineInstr::print(std::ostream &OS, const TargetMachine *TM) const { getOperand(i).print(OS, TM); } + if (getNumMemOperands() > 0) { + OS << ", SV:"; + for (unsigned i = 0; i < getNumMemOperands(); i++) { + const MemOperand &MRO = getMemOperand(i); + const Value *V = MRO.getValue(); + + assert(V && "SV missing."); + assert((MRO.isLoad() || MRO.isStore()) && + "SV has to be a load, store or both."); + + if (MRO.isVolatile()) + OS << "Volatile "; + if (MRO.isLoad()) + OS << "LD "; + if (MRO.isStore()) + OS << "ST "; + + OS << MRO.getSize(); + + if (!V->getName().empty()) + OS << "[" << V->getName() << " + " << MRO.getOffset() << "]"; + else if (isa<PseudoSourceValue>(V)) + OS << "[" << *V << " + " << MRO.getOffset() << "]"; + else + OS << "[" << V << " + " << MRO.getOffset() << "]"; + } + } + OS << "\n"; } diff --git a/lib/CodeGen/PseudoSourceValue.cpp b/lib/CodeGen/PseudoSourceValue.cpp index e69de29bb2..b7fb25e4f1 100644 --- a/lib/CodeGen/PseudoSourceValue.cpp +++ b/lib/CodeGen/PseudoSourceValue.cpp @@ -0,0 +1,41 @@ +//===-- llvm/CodeGen/PseudoSourceValue.cpp ----------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the PseudoSourceValue class. +// +//===----------------------------------------------------------------------===// + +#include "llvm/CodeGen/PseudoSourceValue.h" +#include "llvm/DerivedTypes.h" +#include "llvm/Support/ManagedStatic.h" + +namespace llvm { + static ManagedStatic<PseudoSourceValue[5]> PSVs; + + const PseudoSourceValue &PseudoSourceValue::getFixedStack() { return (*PSVs)[0]; } + const PseudoSourceValue &PseudoSourceValue::getStack() { return (*PSVs)[1]; } + const PseudoSourceValue &PseudoSourceValue::getGOT() { return (*PSVs)[2]; } + const PseudoSourceValue &PseudoSourceValue::getConstantPool() { return (*PSVs)[3]; } + const PseudoSourceValue &PseudoSourceValue::getJumpTable() { return (*PSVs)[4]; } + + static const char *PSVNames[] = { + "FixedStack", + "Stack", + "GOT", + "ConstantPool", + "JumpTable" + }; + + PseudoSourceValue::PseudoSourceValue() : + Value(PointerType::getUnqual(Type::Int8Ty), PseudoSourceValueVal) {} + + void PseudoSourceValue::print(std::ostream &OS) const { + OS << PSVNames[this - *PSVs]; + } +} diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index 4749b76344..71633fe7cd 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -16,6 +16,7 @@ #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineJumpTableInfo.h" #include "llvm/CodeGen/MachineModuleInfo.h" +#include "llvm/CodeGen/PseudoSourceValue.h" #include "llvm/Target/TargetFrameInfo.h" #include "llvm/Target/TargetLowering.h" #include "llvm/Target/TargetData.h" @@ -509,9 +510,11 @@ static SDOperand ExpandConstantFP(ConstantFPSDNode *CFP, bool UseCP, SDOperand CPIdx = DAG.getConstantPool(LLVMC, TLI.getPointerTy()); if (Extend) { return DAG.getExtLoad(ISD::EXTLOAD, MVT::f64, DAG.getEntryNode(), - CPIdx, NULL, 0, MVT::f32); + CPIdx, &PseudoSourceValue::getConstantPool(), + 0, MVT::f32); } else { - return DAG.getLoad(VT, DAG.getEntryNode(), CPIdx, NULL, 0); + return DAG.getLoad(VT, DAG.getEntryNode(), CPIdx, + &PseudoSourceValue::getConstantPool(), 0); } } @@ -796,6 +799,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { case ISD::TargetExternalSymbol: case ISD::VALUETYPE: case ISD::SRCVALUE: + case ISD::MEMOPERAND: case ISD::STRING: case ISD::CONDCODE: // Primitives must all be legal. @@ -1316,8 +1320,15 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { MVT::ValueType IdxVT = Tmp3.getValueType(); MVT::ValueType PtrVT = TLI.getPointerTy(); SDOperand StackPtr = DAG.CreateStackTemporary(VT); + + FrameIndexSDNode *StackPtrFI = dyn_cast<FrameIndexSDNode>(StackPtr.Val); + assert(StackPtrFI); + int SPFI = StackPtrFI->getIndex(); + // Store the vector. - SDOperand Ch = DAG.getStore(DAG.getEntryNode(), Tmp1, StackPtr, NULL, 0); + SDOperand Ch = DAG.getStore(DAG.getEntryNode(), Tmp1, StackPtr, + &PseudoSourceValue::getFixedStack(), + SPFI); // Truncate or zero extend offset to target pointer type. unsigned CastOpc = (IdxVT > PtrVT) ? ISD::TRUNCATE : ISD::ZERO_EXTEND; @@ -1327,9 +1338,11 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { Tmp3 = DAG.getNode(ISD::MUL, IdxVT, Tmp3,DAG.getConstant(EltSize, IdxVT)); SDOperand StackPtr2 = DAG.getNode(ISD::ADD, IdxVT, Tmp3, StackPtr); // Store the scalar value. - Ch = DAG.getStore(Ch, Tmp2, StackPtr2, NULL, 0); + Ch = DAG.getStore(Ch, Tmp2, StackPtr2, + &PseudoSourceValue::getFixedStack(), SPFI); // Load the updated vector. - Result = DAG.getLoad(VT, Ch, StackPtr, NULL, 0); + Result = DAG.getLoad(VT, Ch, StackPtr, + &PseudoSourceValue::getFixedStack(), SPFI); break; } } @@ -1678,8 +1691,10 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { SDOperand LD; switch (EntrySize) { default: assert(0 && "Size of jump table not supported yet."); break; - case 4: LD = DAG.getLoad(MVT::i32, Chain, Addr, NULL, 0); break; - case 8: LD = DAG.getLoad(MVT::i64, Chain, Addr, NULL, 0); break; + case 4: LD = DAG.getLoad(MVT::i32, Chain, Addr, + &PseudoSourceValue::getJumpTable(), 0); break; + case 8: LD = DAG.getLoad(MVT::i64, Chain, Addr, + &PseudoSourceValue::getJumpTable(), 0); break; } Addr = LD; @@ -3240,16 +3255,14 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { } break; case TargetLowering::Expand: { - SrcValueSDNode *SV = cast<SrcValueSDNode>(Node->getOperand(2)); - SDOperand VAList = DAG.getLoad(TLI.getPointerTy(), Tmp1, Tmp2, - SV->getValue(), SV->getOffset()); + const Value *V = cast<SrcValueSDNode>(Node->getOperand(2))->getValue(); + SDOperand VAList = DAG.getLoad(TLI.getPointerTy(), Tmp1, Tmp2, V, 0); // Increment the pointer, VAList, to the next vaarg Tmp3 = DAG.getNode(ISD::ADD, TLI.getPointerTy(), VAList, DAG.getConstant(MVT::getSizeInBits(VT)/8, TLI.getPointerTy())); // Store the incremented VAList to the legalized pointer - Tmp3 = DAG.getStore(VAList.getValue(1), Tmp3, Tmp2, SV->getValue(), - SV->getOffset()); + Tmp3 = DAG.getStore(VAList.getValue(1), Tmp3, Tmp2, V, 0); // Load the actual argument out of the pointer VAList Result = DAG.getLoad(VT, Tmp3, VAList, NULL, 0); Tmp1 = LegalizeOp(Result.getValue(1)); @@ -3285,12 +3298,10 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { case TargetLowering::Expand: // This defaults to loading a pointer from the input and storing it to the // output, returning the chain. - SrcValueSDNode *SVD = cast<SrcValueSDNode>(Node->getOperand(3)); - SrcValueSDNode *SVS = cast<SrcValueSDNode>(Node->getOperand(4)); - Tmp4 = DAG.getLoad(TLI.getPointerTy(), Tmp1, Tmp3, SVD->getValue(), - SVD->getOffset()); - Result = DAG.getStore(Tmp4.getValue(1), Tmp4, Tmp2, SVS->getValue(), - SVS->getOffset()); + const Value *VD = cast<SrcValueSDNode>(Node->getOperand(3))->getValue(); + const Value *VS = cast<SrcValueSDNode>(Node->getOperand(4))->getValue(); + Tmp4 = DAG.getLoad(TLI.getPointerTy(), Tmp1, Tmp3, VD, 0); + Result = DAG.getStore(Tmp4.getValue(1), Tmp4, Tmp2, VS, 0); break; } break; @@ -4285,16 +4296,14 @@ SDOperand SelectionDAGLegalize::PromoteOp(SDOperand Op) { Tmp3 = DAG.getVAArg(VT, Tmp1, Tmp2, Node->getOperand(2)); Result = TLI.CustomPromoteOperation(Tmp3, DAG); } else { - SrcValueSDNode *SV = cast<SrcValueSDNode>(Node->getOperand(2)); - SDOperand VAList = DAG.getLoad(TLI.getPointerTy(), Tmp1, Tmp2, - SV->getValue(), SV->getOffset()); + const Value *V = cast<SrcValueSDNode>(Node->getOperand(2))->getValue(); + SDOperand VAList = DAG.getLoad(TLI.getPointerTy(), Tmp1, Tmp2, V, 0); // Increment the pointer, VAList, to the next vaarg Tmp3 = DAG.getNode(ISD::ADD, TLI.getPointerTy(), VAList, DAG.getConstant(MVT::getSizeInBits(VT)/8, TLI.getPointerTy())); // Store the incremented VAList to the legalized pointer - Tmp3 = DAG.getStore(VAList.getValue(1), Tmp3, Tmp2, SV->getValue(), - SV->getOffset()); + Tmp3 = DAG.getStore(VAList.getValue(1), Tmp3, Tmp2, V, 0); // Load the actual argument out of the pointer VAList Result = DAG.getExtLoad(ISD::EXTLOAD, NVT, Tmp3, VAList, NULL, 0, VT); } @@ -4750,6 +4759,10 @@ SDOperand SelectionDAGLegalize::EmitStackConvert(SDOperand SrcOp, // Create the stack frame object. SDOperand FIPtr = DAG.CreateStackTemporary(SlotVT); + FrameIndexSDNode *StackPtrFI = dyn_cast<FrameIndexSDNode>(FIPtr); + assert(StackPtrFI); + int SPFI = StackPtrFI->getIndex(); + unsigned SrcSize = MVT::getSizeInBits(SrcOp.getValueType()); unsigned SlotSize = MVT::getSizeInBits(SlotVT); unsigned DestSize = MVT::getSizeInBits(DestVT); @@ -4758,10 +4771,14 @@ SDOperand SelectionDAGLegalize::EmitStackConvert(SDOperand SrcOp, // later than DestVT. SDOperand Store; if (SrcSize > SlotSize) - Store = DAG.getTruncStore(DAG.getEntryNode(), SrcOp, FIPtr, NULL, 0,SlotVT); + Store = DAG.getTruncStore(DAG.getEntryNode(), SrcOp, FIPtr, + &PseudoSourceValue::getFixedStack(), + SPFI, SlotVT); else { assert(SrcSize == SlotSize && "Invalid store"); - Store = DAG.getStore(DAG.getEntryNode(), SrcOp, FIPtr, NULL, 0); + Store = DAG.getStore(DAG.getEntryNode(), SrcOp, FIPtr, + &PseudoSourceValue::getFixedStack(), + SPFI, SlotVT); } // Result is a load from the stack slot. @@ -4776,9 +4793,15 @@ SDOperand SelectionDAGLegalize::ExpandSCALAR_TO_VECTOR(SDNode *Node) { // Create a vector sized/aligned stack slot, store the value to element #0, // then load the whole vector back out. SDOperand StackPtr = DAG.CreateStackTemporary(Node->getValueType(0)); + + FrameIndexSDNode *StackPtrFI = dyn_cast<FrameIndexSDNode>(StackPtr); + assert(StackPtrFI); + int SPFI = StackPtrFI->getIndex(); + SDOperand Ch = DAG.getStore(DAG.getEntryNode(), Node->getOperand(0), StackPtr, - NULL, 0); - return DAG.getLoad(Node->getValueType(0), Ch, StackPtr, NULL, 0); + &PseudoSourceValue::getFixedStack(), SPFI); + return DAG.getLoad(Node->getValueType(0), Ch, StackPtr, + &PseudoSourceValue::getFixedStack(), SPFI); } @@ -4842,7 +4865,8 @@ SDOperand SelectionDAGLegalize::ExpandBUILD_VECTOR(SDNode *Node) { } Constant *CP = ConstantVector::get(CV); SDOperand CPIdx = DAG.getConstantPool(CP, TLI.getPointerTy()); - return DAG.getLoad(VT, DAG.getEntryNode(), CPIdx, NULL, 0); + return DAG.getLoad(VT, DAG.getEntryNode(), CPIdx, + &PseudoSourceValue::getConstantPool(), 0); } if (SplatValue.Val) { // Splat of one value? @@ -5184,11 +5208,14 @@ ExpandIntToFP(bool isSigned, MVT::ValueType DestTy, SDOperand Source) { CPIdx = DAG.getNode(ISD::ADD, TLI.getPointerTy(), CPIdx, CstOffset); SDOperand FudgeInReg; if (DestTy == MVT::f32) - FudgeInReg = DAG.getLoad(MVT::f32, DAG.getEntryNode(), CPIdx, NULL, 0); + FudgeInReg = DAG.getLoad(MVT::f32, DAG.getEntryNode(), CPIdx, + &PseudoSourceValue::getConstantPool(), 0); else if (MVT::getSizeInBits(DestTy) > MVT::getSizeInBits(MVT::f32)) // FIXME: Avoid the extend by construction the right constantpool? FudgeInReg = DAG.getExtLoad(ISD::EXTLOAD, DestTy, DAG.getEntryNode(), - CPIdx, NULL, 0, MVT::f32); + CPIdx, + &PseudoSourceValue::getConstantPool(), 0, + MVT::f32); else assert(0 && "Unexpected conversion"); @@ -5330,11 +5357,14 @@ SDOperand SelectionDAGLegalize::ExpandLegalINT_TO_FP(bool isSigned, CPIdx = DAG.getNode(ISD::ADD, TLI.getPointerTy(), CPIdx, CstOffset); SDOperand FudgeInReg; if (DestVT == MVT::f32) - FudgeInReg = DAG.getLoad(MVT::f32, DAG.getEntryNode(), CPIdx, NULL, 0); + FudgeInReg = DAG.getLoad(MVT::f32, DAG.getEntryNode(), CPIdx, + &PseudoSourceValue::getConstantPool(), 0); else { - FudgeInReg = LegalizeOp(DAG.getExtLoad(ISD::EXTLOAD, DestVT, - DAG.getEntryNode(), CPIdx, - NULL, 0, MVT::f32)); + FudgeInReg = + LegalizeOp(DAG.getExtLoad(ISD::EXTLOAD, DestVT, + DAG.getEntryNode(), CPIdx, + &PseudoSourceValue::getConstantPool(), 0, + MVT::f32)); } return DAG.getNode(ISD::FADD, DestVT, Tmp1, FudgeInReg); @@ -6743,10 +6773,16 @@ void SelectionDAGLegalize::SplitVectorOp(SDOperand Op, SDOperand &Lo, // Lower to a store/load so that it can be split. // FIXME: this could be improved probably. SDOperand Ptr = DAG.CreateStackTemporary(InOp.getValueType()); + FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(Ptr.Val); + assert(FI && "Expecting CreateStackTemporary to return a frame index.\n"); SDOperand St = DAG.getStore(DAG.getEntryNode(), - InOp, Ptr, NULL, 0); - InOp = DAG.getLoad(Op.getValueType(), St, Ptr, NULL, 0); + InOp, Ptr, + &PseudoSourceValue::getFixedStack(), + FI->getIndex()); + InOp = DAG.getLoad(Op.getValueType(), St, Ptr, + &PseudoSourceValue::getFixedStack(), + FI->getIndex()); } // Split the vector and convert each of the pieces now. SplitVectorOp(InOp, Lo, Hi); diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp index a165b17dff..043f7c1cb2 100644 --- a/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp +++ b/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp @@ -277,15 +277,27 @@ unsigned ScheduleDAG::CountResults(SDNode *Node) { return N; } -/// CountOperands The inputs to target nodes have any actual inputs first, -/// followed by an optional chain operand, then flag operands. Compute the -/// number of actual operands that will go into the machine instr. +/// CountOperands - The inputs to target nodes have any actu |