mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
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. llvm-svn: 46827
This commit is contained in:
parent
6b03a1aeb9
commit
f00842e086
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
@ -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
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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 ||
|
||||
|
@ -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:
|
||||
|
@ -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";
|
||||
}
|
||||
|
||||
|
@ -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];
|
||||
}
|
||||
}
|
@ -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);
|
||||
|
@ -277,10 +277,22 @@ 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 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 istr.
|
||||
unsigned ScheduleDAG::CountOperands(SDNode *Node) {
|
||||
unsigned N = Node->getNumOperands();
|
||||
while (N && Node->getOperand(N - 1).getValueType() == MVT::Flag)
|
||||
--N;
|
||||
if (N && Node->getOperand(N - 1).getValueType() == MVT::Other)
|
||||
--N; // Ignore chain if it exists.
|
||||
while (N && MemOperandSDNode::classof(Node->getOperand(N - 1).Val))
|
||||
--N; // Ignore MemOperand nodes
|
||||
return N;
|
||||
}
|
||||
|
||||
/// CountMemOperands - Find the index of the last MemOperandSDNode operand
|
||||
unsigned ScheduleDAG::CountMemOperands(SDNode *Node) {
|
||||
unsigned N = Node->getNumOperands();
|
||||
while (N && Node->getOperand(N - 1).getValueType() == MVT::Flag)
|
||||
--N;
|
||||
@ -517,6 +529,10 @@ void ScheduleDAG::AddOperand(MachineInstr *MI, SDOperand Op,
|
||||
|
||||
}
|
||||
|
||||
void ScheduleDAG::AddMemOperand(MachineInstr *MI, const MemOperand &MO) {
|
||||
MI->addMemOperand(MO);
|
||||
}
|
||||
|
||||
// Returns the Register Class of a subregister
|
||||
static const TargetRegisterClass *getSubRegisterRegClass(
|
||||
const TargetRegisterClass *TRC,
|
||||
@ -675,6 +691,7 @@ void ScheduleDAG::EmitNode(SDNode *Node, unsigned InstanceNo,
|
||||
|
||||
unsigned NumResults = CountResults(Node);
|
||||
unsigned NodeOperands = CountOperands(Node);
|
||||
unsigned NodeMemOperands = CountMemOperands(Node);
|
||||
unsigned NumMIOperands = NodeOperands + NumResults;
|
||||
bool HasPhysRegOuts = (NumResults > II.getNumDefs()) &&
|
||||
II.getImplicitDefs() != 0;
|
||||
@ -697,6 +714,10 @@ void ScheduleDAG::EmitNode(SDNode *Node, unsigned InstanceNo,
|
||||
for (unsigned i = 0; i != NodeOperands; ++i)
|
||||
AddOperand(MI, Node->getOperand(i), i+II.getNumDefs(), &II, VRBaseMap);
|
||||
|
||||
// Emit all of the memory operands of this instruction
|
||||
for (unsigned i = NodeOperands; i != NodeMemOperands; ++i)
|
||||
AddMemOperand(MI, cast<MemOperandSDNode>(Node->getOperand(i))->MO);
|
||||
|
||||
// Commute node if it has been determined to be profitable.
|
||||
if (CommuteSet.count(Node)) {
|
||||
MachineInstr *NewMI = TII->commuteInstruction(MI);
|
||||
@ -737,6 +758,7 @@ void ScheduleDAG::EmitNode(SDNode *Node, unsigned InstanceNo,
|
||||
case ISD::TokenFactor:
|
||||
case ISD::LABEL:
|
||||
case ISD::DECLARE:
|
||||
case ISD::SRCVALUE:
|
||||
break;
|
||||
case ISD::CopyToReg: {
|
||||
unsigned InReg;
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "llvm/CodeGen/MachineConstantPool.h"
|
||||
#include "llvm/CodeGen/MachineFrameInfo.h"
|
||||
#include "llvm/CodeGen/MachineModuleInfo.h"
|
||||
#include "llvm/CodeGen/PseudoSourceValue.h"
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
#include "llvm/Target/MRegisterInfo.h"
|
||||
#include "llvm/Target/TargetData.h"
|
||||
@ -361,10 +362,16 @@ static void AddNodeIDNode(FoldingSetNodeID &ID, SDNode *N) {
|
||||
case ISD::Register:
|
||||
ID.AddInteger(cast<RegisterSDNode>(N)->getReg());
|
||||
break;
|
||||
case ISD::SRCVALUE: {
|
||||
SrcValueSDNode *SV = cast<SrcValueSDNode>(N);
|
||||
ID.AddPointer(SV->getValue());
|
||||
ID.AddInteger(SV->getOffset());
|
||||
case ISD::SRCVALUE:
|
||||
ID.AddPointer(cast<SrcValueSDNode>(N)->getValue());
|
||||
break;
|
||||
case ISD::MEMOPERAND: {
|
||||
const MemOperand &MO = cast<MemOperandSDNode>(N)->MO;
|
||||
ID.AddPointer(MO.getValue());
|
||||
ID.AddInteger(MO.getFlags());
|
||||
ID.AddInteger(MO.getOffset());
|
||||
ID.AddInteger(MO.getSize());
|
||||
ID.AddInteger(MO.getAlignment());
|
||||
break;
|
||||
}
|
||||
case ISD::FrameIndex:
|
||||
@ -937,18 +944,42 @@ SDOperand SelectionDAG::getRegister(unsigned RegNo, MVT::ValueType VT) {
|
||||
return SDOperand(N, 0);
|
||||
}
|
||||
|
||||
SDOperand SelectionDAG::getSrcValue(const Value *V, int Offset) {
|
||||
SDOperand SelectionDAG::getSrcValue(const Value *V) {
|
||||
assert((!V || isa<PointerType>(V->getType())) &&
|
||||
"SrcValue is not a pointer?");
|
||||
|
||||
FoldingSetNodeID ID;
|
||||
AddNodeIDNode(ID, ISD::SRCVALUE, getVTList(MVT::Other), 0, 0);
|
||||
ID.AddPointer(V);
|
||||
ID.AddInteger(Offset);
|
||||
|
||||
void *IP = 0;
|
||||
if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
|
||||
return SDOperand(E, 0);
|
||||
SDNode *N = new SrcValueSDNode(V, Offset);
|
||||
|
||||
SDNode *N = new SrcValueSDNode(V);
|
||||
CSEMap.InsertNode(N, IP);
|
||||
AllNodes.push_back(N);
|
||||
return SDOperand(N, 0);
|
||||
}
|
||||
|
||||
SDOperand SelectionDAG::getMemOperand(const MemOperand &MO) {
|
||||
const Value *v = MO.getValue();
|
||||
assert((!v || isa<PointerType>(v->getType())) &&
|
||||
"SrcValue is not a pointer?");
|
||||
|
||||
FoldingSetNodeID ID;
|
||||
AddNodeIDNode(ID, ISD::MEMOPERAND, getVTList(MVT::Other), 0, 0);
|
||||
ID.AddPointer(v);
|
||||
ID.AddInteger(MO.getFlags());
|
||||
ID.AddInteger(MO.getOffset());
|
||||
ID.AddInteger(MO.getSize());
|
||||
ID.AddInteger(MO.getAlignment());
|
||||
|
||||
void *IP = 0;
|
||||
if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
|
||||
return SDOperand(E, 0);
|
||||
|
||||
SDNode *N = new MemOperandSDNode(MO);
|
||||
CSEMap.InsertNode(N, IP);
|
||||
AllNodes.push_back(N);
|
||||
return SDOperand(N, 0);
|
||||
@ -3479,6 +3510,7 @@ void JumpTableSDNode::ANCHOR() {}
|
||||
void ConstantPoolSDNode::ANCHOR() {}
|
||||
void BasicBlockSDNode::ANCHOR() {}
|
||||
void SrcValueSDNode::ANCHOR() {}
|
||||
void MemOperandSDNode::ANCHOR() {}
|
||||
void RegisterSDNode::ANCHOR() {}
|
||||
void ExternalSymbolSDNode::ANCHOR() {}
|
||||
void CondCodeSDNode::ANCHOR() {}
|
||||
@ -3503,6 +3535,26 @@ GlobalAddressSDNode::GlobalAddressSDNode(bool isTarget, const GlobalValue *GA,
|
||||
TheGlobal = const_cast<GlobalValue*>(GA);
|
||||
}
|
||||
|
||||
/// getMemOperand - Return a MemOperand object describing the memory
|
||||
/// reference performed by this load or store.
|
||||
MemOperand LSBaseSDNode::getMemOperand() const {
|
||||
int Size = (MVT::getSizeInBits(getMemoryVT()) + 7) >> 3;
|
||||
int Flags =
|
||||
getOpcode() == ISD::LOAD ? MemOperand::MOLoad : MemOperand::MOStore;
|
||||
if (IsVolatile) Flags |= MemOperand::MOVolatile;
|
||||
|
||||
// Check if the load references a frame index, and does not have
|
||||
// an SV attached.
|
||||
const FrameIndexSDNode *FI =
|
||||
dyn_cast<const FrameIndexSDNode>(getBasePtr().Val);
|
||||
if (!getSrcValue() && FI)
|
||||
return MemOperand(&PseudoSourceValue::getFixedStack(), Flags,
|
||||
FI->getIndex(), Size, Alignment);
|
||||
else
|
||||
return MemOperand(getSrcValue(), Flags,
|
||||
getSrcValueOffset(), Size, Alignment);
|
||||
}
|
||||
|
||||
/// Profile - Gather unique data for the node.
|
||||
///
|
||||
void SDNode::Profile(FoldingSetNodeID &ID) {
|
||||
@ -3695,6 +3747,7 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const {
|
||||
case ISD::PCMARKER: return "PCMarker";
|
||||
case ISD::READCYCLECOUNTER: return "ReadCycleCounter";
|
||||
case ISD::SRCVALUE: return "SrcValue";
|
||||
case ISD::MEMOPERAND: return "MemOperand";
|
||||
case ISD::EntryToken: return "EntryToken";
|
||||
case ISD::TokenFactor: return "TokenFactor";
|
||||
case ISD::AssertSext: return "AssertSext";
|
||||
@ -4000,9 +4053,14 @@ void SDNode::dump(const SelectionDAG *G) const {
|
||||
cerr << "'" << ES->getSymbol() << "'";
|
||||
} else if (const SrcValueSDNode *M = dyn_cast<SrcValueSDNode>(this)) {
|
||||
if (M->getValue())
|
||||
cerr << "<" << M->getValue() << ":" << M->getOffset() << ">";
|
||||
cerr << "<" << M->getValue() << ">";
|
||||
else
|
||||
cerr << "<null:" << M->getOffset() << ">";
|
||||
cerr << "<null>";
|
||||
} else if (const MemOperandSDNode *M = dyn_cast<MemOperandSDNode>(this)) {
|
||||
if (M->MO.getValue())
|
||||
cerr << "<" << M->MO.getValue() << ":" << M->MO.getOffset() << ">";
|
||||
else
|
||||
cerr << "<null:" << M->MO.getOffset() << ">";
|
||||
} else if (const VTSDNode *N = dyn_cast<VTSDNode>(this)) {
|
||||
cerr << ":" << MVT::getValueTypeString(N->getVT());
|
||||
} else if (const LoadSDNode *LD = dyn_cast<LoadSDNode>(this)) {
|
||||
|
@ -142,9 +142,14 @@ std::string DOTGraphTraits<SelectionDAG*>::getNodeLabel(const SDNode *Node,
|
||||
Op += "'" + std::string(ES->getSymbol()) + "'";
|
||||
} else if (const SrcValueSDNode *M = dyn_cast<SrcValueSDNode>(Node)) {
|
||||
if (M->getValue())
|
||||
Op += "<" + M->getValue()->getName() + ":" + itostr(M->getOffset()) + ">";
|
||||
Op += "<" + M->getValue()->getName() + ">";
|
||||
else
|
||||
Op += "<null:" + itostr(M->getOffset()) + ">";
|
||||
Op += "<null>";
|
||||
} else if (const MemOperandSDNode *M = dyn_cast<MemOperandSDNode>(Node)) {
|
||||
if (M->MO.getValue())
|
||||
Op += "<" + M->MO.getValue()->getName() + ":" + itostr(M->MO.getOffset()) + ">";
|
||||
else
|
||||
Op += "<null:" + itostr(M->MO.getOffset()) + ">";
|
||||
} else if (const VTSDNode *N = dyn_cast<VTSDNode>(Node)) {
|
||||
Op = Op + " VT=" + MVT::getValueTypeString(N->getVT());
|
||||
} else if (const StringSDNode *N = dyn_cast<StringSDNode>(Node)) {
|
||||
|
@ -905,9 +905,8 @@ static SDOperand LowerVASTART(SDOperand Op, SelectionDAG &DAG,
|
||||
// memory location argument.
|
||||
MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
|
||||
SDOperand FR = DAG.getFrameIndex(VarArgsFrameIndex, PtrVT);
|
||||
SrcValueSDNode *SV = cast<SrcValueSDNode>(Op.getOperand(2));
|
||||
return DAG.getStore(Op.getOperand(0), FR, Op.getOperand(1), SV->getValue(),
|
||||
SV->getOffset());
|
||||
const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
|
||||
return DAG.getStore(Op.getOperand(0), FR, Op.getOperand(1), SV, 0);
|
||||
}
|
||||
|
||||
static SDOperand LowerFORMAL_ARGUMENT(SDOperand Op, SelectionDAG &DAG,
|
||||
|
@ -491,10 +491,9 @@ SDOperand AlphaTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
|
||||
case ISD::VAARG: {
|
||||
SDOperand Chain = Op.getOperand(0);
|
||||
SDOperand VAListP = Op.getOperand(1);
|
||||
SrcValueSDNode *VAListS = cast<SrcValueSDNode>(Op.getOperand(2));
|
||||
const Value *VAListS = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
|
||||
|
||||
SDOperand Base = DAG.getLoad(MVT::i64, Chain, VAListP, VAListS->getValue(),
|
||||
VAListS->getOffset());
|
||||
SDOperand Base = DAG.getLoad(MVT::i64, Chain, VAListP, VAListS, 0);
|
||||
SDOperand Tmp = DAG.getNode(ISD::ADD, MVT::i64, VAListP,
|
||||
DAG.getConstant(8, MVT::i64));
|
||||
SDOperand Offset = DAG.getExtLoad(ISD::SEXTLOAD, MVT::i64, Base.getValue(1),
|
||||
@ -527,13 +526,11 @@ SDOperand AlphaTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
|
||||
SDOperand Chain = Op.getOperand(0);
|
||||
SDOperand DestP = Op.getOperand(1);
|
||||
SDOperand SrcP = Op.getOperand(2);
|
||||
SrcValueSDNode *DestS = cast<SrcValueSDNode>(Op.getOperand(3));
|
||||
SrcValueSDNode *SrcS = cast<SrcValueSDNode>(Op.getOperand(4));
|
||||
const Value *DestS = cast<SrcValueSDNode>(Op.getOperand(3))->getValue();
|
||||
const Value *SrcS = cast<SrcValueSDNode>(Op.getOperand(4))->getValue();
|
||||
|
||||
SDOperand Val = DAG.getLoad(getPointerTy(), Chain, SrcP,
|
||||
SrcS->getValue(), SrcS->getOffset());
|
||||
SDOperand Result = DAG.getStore(Val.getValue(1), Val, DestP, DestS->getValue(),
|
||||
DestS->getOffset());
|
||||
SDOperand Val = DAG.getLoad(getPointerTy(), Chain, SrcP, SrcS, 0);
|
||||
SDOperand Result = DAG.getStore(Val.getValue(1), Val, DestP, DestS, 0);
|
||||
SDOperand NP = DAG.getNode(ISD::ADD, MVT::i64, SrcP,
|
||||
DAG.getConstant(8, MVT::i64));
|
||||
Val = DAG.getExtLoad(ISD::SEXTLOAD, MVT::i64, Result, NP, NULL,0, MVT::i32);
|
||||
@ -544,12 +541,11 @@ SDOperand AlphaTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
|
||||
case ISD::VASTART: {
|
||||
SDOperand Chain = Op.getOperand(0);
|
||||
SDOperand VAListP = Op.getOperand(1);
|
||||
SrcValueSDNode *VAListS = cast<SrcValueSDNode>(Op.getOperand(2));
|
||||
const Value *VAListS = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
|
||||
|
||||
// vastart stores the address of the VarArgsBase and VarArgsOffset
|
||||
SDOperand FR = DAG.getFrameIndex(VarArgsBase, MVT::i64);
|
||||
SDOperand S1 = DAG.getStore(Chain, FR, VAListP, VAListS->getValue(),
|
||||
VAListS->getOffset());
|
||||
SDOperand S1 = DAG.getStore(Chain, FR, VAListP, VAListS, 0);
|
||||
SDOperand SA2 = DAG.getNode(ISD::ADD, MVT::i64, VAListP,
|
||||
DAG.getConstant(8, MVT::i64));
|
||||
return DAG.getTruncStore(S1, DAG.getConstant(VarArgsOffset, MVT::i64),
|
||||
|
@ -581,16 +581,16 @@ LowerOperation(SDOperand Op, SelectionDAG &DAG) {
|
||||
}
|
||||
case ISD::VAARG: {
|
||||
MVT::ValueType VT = getPointerTy();
|
||||
SrcValueSDNode *SV = cast<SrcValueSDNode>(Op.getOperand(2));
|
||||
const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
|
||||
SDOperand VAList = DAG.getLoad(VT, Op.getOperand(0), Op.getOperand(1),
|
||||
SV->getValue(), SV->getOffset());
|
||||
SV, 0);
|
||||
// Increment the pointer, VAList, to the next vaarg
|
||||
SDOperand VAIncr = DAG.getNode(ISD::ADD, VT, VAList,
|
||||
DAG.getConstant(MVT::getSizeInBits(VT)/8,
|
||||
VT));
|
||||
// Store the incremented VAList to the legalized pointer
|
||||
VAIncr = DAG.getStore(VAList.getValue(1), VAIncr,
|
||||
Op.getOperand(1), SV->getValue(), SV->getOffset());
|
||||
Op.getOperand(1), SV, 0);
|
||||
// Load the actual argument out of the pointer VAList
|
||||
return DAG.getLoad(Op.getValueType(), VAIncr, VAList, NULL, 0);
|
||||
}
|
||||
@ -598,9 +598,8 @@ LowerOperation(SDOperand Op, SelectionDAG &DAG) {
|
||||
// vastart just stores the address of the VarArgsFrameIndex slot into the
|
||||
// memory location argument.
|
||||
SDOperand FR = DAG.getFrameIndex(VarArgsFrameIndex, MVT::i64);
|
||||
SrcValueSDNode *SV = cast<SrcValueSDNode>(Op.getOperand(2));
|
||||
return DAG.getStore(Op.getOperand(0), FR,
|
||||
Op.getOperand(1), SV->getValue(), SV->getOffset());
|
||||
const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
|
||||
return DAG.getStore(Op.getOperand(0), FR, Op.getOperand(1), SV, 0);
|
||||
}
|
||||
// Frame & Return address. Currently unimplemented
|
||||
case ISD::RETURNADDR: break;
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "llvm/CodeGen/MachineFunction.h"
|
||||
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
#include "llvm/CodeGen/PseudoSourceValue.h"
|
||||
#include "llvm/CodeGen/SelectionDAG.h"
|
||||
#include "llvm/Constants.h"
|
||||
#include "llvm/Function.h"
|
||||
@ -1175,9 +1176,8 @@ static SDOperand LowerVASTART(SDOperand Op, SelectionDAG &DAG,
|
||||
// memory location argument.
|
||||
MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
|
||||
SDOperand FR = DAG.getFrameIndex(VarArgsFrameIndex, PtrVT);
|
||||
SrcValueSDNode *SV = cast<SrcValueSDNode>(Op.getOperand(2));
|
||||
return DAG.getStore(Op.getOperand(0), FR, Op.getOperand(1), SV->getValue(),
|
||||
SV->getOffset());
|
||||
const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
|
||||
return DAG.getStore(Op.getOperand(0), FR, Op.getOperand(1), SV, 0);
|
||||
}
|
||||
|
||||
// For ELF 32 ABI we follow the layout of the va_list struct.
|
||||
@ -1211,37 +1211,41 @@ static SDOperand LowerVASTART(SDOperand Op, SelectionDAG &DAG,
|
||||
|
||||
MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
|
||||
|
||||
SDOperand StackOffset = DAG.getFrameIndex(VarArgsStackOffset, PtrVT);
|
||||
SDOperand StackOffsetFI = DAG.getFrameIndex(VarArgsStackOffset, PtrVT);
|
||||
SDOperand FR = DAG.getFrameIndex(VarArgsFrameIndex, PtrVT);
|
||||
|
||||
SDOperand ConstFrameOffset = DAG.getConstant(MVT::getSizeInBits(PtrVT)/8,
|
||||
PtrVT);
|
||||
SDOperand ConstStackOffset = DAG.getConstant(MVT::getSizeInBits(PtrVT)/8 - 1,
|
||||
PtrVT);
|
||||
SDOperand ConstFPROffset = DAG.getConstant(1, PtrVT);
|
||||
uint64_t FrameOffset = MVT::getSizeInBits(PtrVT)/8;
|
||||
SDOperand ConstFrameOffset = DAG.getConstant(FrameOffset, PtrVT);
|
||||
|
||||
uint64_t StackOffset = MVT::getSizeInBits(PtrVT)/8 - 1;
|
||||
SDOperand ConstStackOffset = DAG.getConstant(StackOffset, PtrVT);
|
||||
|
||||
uint64_t FPROffset = 1;
|
||||
SDOperand ConstFPROffset = DAG.getConstant(FPROffset, PtrVT);
|
||||
|
||||
SrcValueSDNode *SV = cast<SrcValueSDNode>(Op.getOperand(2));
|
||||
const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
|
||||
|
||||
// Store first byte : number of int regs
|
||||
SDOperand firstStore = DAG.getStore(Op.getOperand(0), ArgGPR,
|
||||
Op.getOperand(1), SV->getValue(),
|
||||
SV->getOffset());
|
||||
Op.getOperand(1), SV, 0);
|
||||
uint64_t nextOffset = FPROffset;
|
||||
SDOperand nextPtr = DAG.getNode(ISD::ADD, PtrVT, Op.getOperand(1),
|
||||
ConstFPROffset);
|
||||
|
||||
// Store second byte : number of float regs
|
||||
SDOperand secondStore = DAG.getStore(firstStore, ArgFPR, nextPtr,
|
||||
SV->getValue(), SV->getOffset());
|
||||
SDOperand secondStore =
|
||||
DAG.getStore(firstStore, ArgFPR, nextPtr, SV, nextOffset);
|
||||
nextOffset += StackOffset;
|
||||
nextPtr = DAG.getNode(ISD::ADD, PtrVT, nextPtr, ConstStackOffset);
|
||||
|
||||
// Store second word : arguments given on stack
|
||||
SDOperand thirdStore = DAG.getStore(secondStore, StackOffset, nextPtr,
|
||||
SV->getValue(), SV->getOffset());
|
||||
SDOperand thirdStore =
|
||||
DAG.getStore(secondStore, StackOffsetFI, nextPtr, SV, nextOffset);
|
||||
nextOffset += FrameOffset;
|
||||
nextPtr = DAG.getNode(ISD::ADD, PtrVT, nextPtr, ConstFrameOffset);
|
||||
|
||||
// Store third word : arguments given in registers
|
||||
return DAG.getStore(thirdStore, FR, nextPtr, SV->getValue(),
|
||||
SV->getOffset());
|
||||
return DAG.getStore(thirdStore, FR, nextPtr, SV, nextOffset);
|
||||
|
||||
}
|
||||
|
||||
@ -2199,9 +2203,11 @@ static SDOperand LowerSINT_TO_FP(SDOperand Op, SelectionDAG &DAG) {
|
||||
Op.getOperand(0));
|
||||
|
||||
// STD the extended value into the stack slot.
|
||||
MemOperand MO(&PseudoSourceValue::getFixedStack(),
|
||||
MemOperand::MOStore, FrameIdx, 8, 8);
|
||||
SDOperand Store = DAG.getNode(PPCISD::STD_32, MVT::Other,
|
||||
DAG.getEntryNode(), Ext64, FIdx,
|
||||
DAG.getSrcValue(NULL));
|
||||
DAG.getMemOperand(MO));
|
||||
// Load the value as a double.
|
||||
SDOperand Ld = DAG.getLoad(MVT::f64, Store, FIdx, NULL, 0);
|
||||
|
||||
@ -3300,11 +3306,11 @@ SDOperand PPCTargetLowering::PerformDAGCombine(SDNode *N,
|
||||
std::vector<MVT::ValueType> VTs;
|
||||
VTs.push_back(MVT::i32);
|
||||
VTs.push_back(MVT::Other);
|
||||
SDOperand SV = DAG.getSrcValue(LD->getSrcValue(), LD->getSrcValueOffset());
|
||||
SDOperand MO = DAG.getMemOperand(LD->getMemOperand());
|
||||
SDOperand Ops[] = {
|
||||
LD->getChain(), // Chain
|
||||
LD->getBasePtr(), // Ptr
|
||||
SV, // SrcValue
|
||||
MO, // MemOperand
|
||||
DAG.getValueType(N->getValueType(0)) // VT
|
||||
};
|
||||
SDOperand BSLoad = DAG.getNode(PPCISD::LBRX, VTs, Ops, 4);
|
||||
|
@ -805,25 +805,23 @@ LowerOperation(SDOperand Op, SelectionDAG &DAG) {
|
||||
SDOperand Offset = DAG.getNode(ISD::ADD, MVT::i32,
|
||||
DAG.getRegister(SP::I6, MVT::i32),
|
||||
DAG.getConstant(VarArgsFrameOffset, MVT::i32));
|
||||
SrcValueSDNode *SV = cast<SrcValueSDNode>(Op.getOperand(2));
|
||||
return DAG.getStore(Op.getOperand(0), Offset,
|
||||
Op.getOperand(1), SV->getValue(), SV->getOffset());
|
||||
const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
|
||||
return DAG.getStore(Op.getOperand(0), Offset, Op.getOperand(1), SV, 0);
|
||||
}
|
||||
case ISD::VAARG: {
|
||||
SDNode *Node = Op.Val;
|
||||
MVT::ValueType VT = Node->getValueType(0);
|
||||
SDOperand InChain = Node->getOperand(0);
|
||||
SDOperand VAListPtr = Node->getOperand(1);
|
||||
SrcValueSDNode *SV = cast<SrcValueSDNode>(Node->getOperand(2));
|
||||
SDOperand VAList = DAG.getLoad(getPointerTy(), InChain, VAListPtr,
|
||||
SV->getValue(), SV->getOffset());
|
||||
const Value *SV = cast<SrcValueSDNode>(Node->getOperand(2))->getValue();
|
||||
SDOperand VAList = DAG.getLoad(getPointerTy(), InChain, VAListPtr, SV, 0);
|
||||
// Increment the pointer, VAList, to the next vaarg
|
||||
SDOperand NextPtr = DAG.getNode(ISD::ADD, getPointerTy(), VAList,
|
||||
DAG.getConstant(MVT::getSizeInBits(VT)/8,
|
||||
getPointerTy()));
|
||||
// Store the incremented VAList to the legalized pointer
|
||||
InChain = DAG.getStore(VAList.getValue(1), NextPtr,
|
||||
VAListPtr, SV->getValue(), SV->getOffset());
|
||||
VAListPtr, SV, 0);
|
||||
// Load the actual argument out of the pointer VAList, unless this is an
|
||||
// f64 load.
|
||||
if (VT != MVT::f64) {
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||
#include "llvm/CodeGen/MachineModuleInfo.h"
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
#include "llvm/CodeGen/PseudoSourceValue.h"
|
||||
#include "llvm/CodeGen/SelectionDAG.h"
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
@ -1089,7 +1090,8 @@ SDOperand X86TargetLowering::LowerMemArgument(SDOperand Op, SelectionDAG &DAG,
|
||||
SDOperand FIN = DAG.getFrameIndex(FI, getPointerTy());
|
||||
if (isByVal)
|
||||
return FIN;
|
||||
return DAG.getLoad(VA.getValVT(), Root, FIN, NULL, 0);
|
||||
return DAG.getLoad(VA.getValVT(), Root, FIN,
|
||||
&PseudoSourceValue::getFixedStack(), FI);
|
||||
}
|
||||
|
||||
SDOperand
|
||||
@ -1217,7 +1219,10 @@ X86TargetLowering::LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG) {
|
||||
unsigned VReg = AddLiveIn(MF, GPR64ArgRegs[NumIntRegs],
|
||||
X86::GR64RegisterClass);
|
||||
SDOperand Val = DAG.getCopyFromReg(Root, VReg, MVT::i64);
|
||||
SDOperand Store = DAG.getStore(Val.getValue(1), Val, FIN, NULL, 0);
|
||||
SDOperand Store =
|
||||
DAG.getStore(Val.getValue(1), Val, FIN,
|
||||
&PseudoSourceValue::getFixedStack(),
|
||||
RegSaveFrameIndex);
|
||||
MemOps.push_back(Store);
|
||||
FIN = DAG.getNode(ISD::ADD, getPointerTy(), FIN,
|
||||
DAG.getIntPtrConstant(8));
|
||||
@ -1230,7 +1235,10 @@ X86TargetLowering::LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG) {
|
||||
unsigned VReg = AddLiveIn(MF, XMMArgRegs[NumXMMRegs],
|
||||
X86::VR128RegisterClass);
|
||||
SDOperand Val = DAG.getCopyFromReg(Root, VReg, MVT::v4f32);
|
||||
SDOperand Store = DAG.getStore(Val.getValue(1), Val, FIN, NULL, 0);
|
||||
SDOperand Store =
|
||||
DAG.getStore(Val.getValue(1), Val, FIN,
|
||||
&PseudoSourceValue::getFixedStack(),
|
||||
RegSaveFrameIndex);
|
||||
MemOps.push_back(Store);
|
||||
FIN = DAG.getNode(ISD::ADD, getPointerTy(), FIN,
|
||||
DAG.getIntPtrConstant(16));
|
||||
@ -1559,7 +1567,9 @@ SDOperand X86TargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG) {
|
||||
Flags, DAG));
|
||||
} else {
|
||||
// Store relative to framepointer.
|
||||
MemOpChains2.push_back(DAG.getStore(Chain, Source, FIN, NULL, 0));
|
||||
MemOpChains2.push_back(
|
||||
DAG.getStore(Chain, Source, FIN,
|
||||
&PseudoSourceValue::getFixedStack(), FI));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3788,7 +3798,8 @@ X86TargetLowering::LowerGlobalAddress(SDOperand Op, SelectionDAG &DAG) {
|
||||
// the GV offset field. Platform check is inside GVRequiresExtraLoad() call
|
||||
// The same applies for external symbols during PIC codegen
|
||||
if (Subtarget->GVRequiresExtraLoad(GV, getTargetMachine(), false))
|
||||
Result = DAG.getLoad(getPointerTy(), DAG.getEntryNode(), Result, NULL, 0);
|
||||
Result = DAG.getLoad(getPointerTy(), DAG.getEntryNode(), Result,
|
||||
&PseudoSourceValue::getGOT(), 0);
|
||||
|
||||
return Result;
|
||||
}
|
||||
@ -3846,7 +3857,8 @@ LowerToTLSExecModel(GlobalAddressSDNode *GA, SelectionDAG &DAG,
|
||||
SDOperand Offset = DAG.getNode(X86ISD::Wrapper, PtrVT, TGA);
|
||||
|
||||
if (GA->getGlobal()->isDeclaration()) // initial exec TLS model
|
||||
Offset = DAG.getLoad(PtrVT, DAG.getEntryNode(), Offset, NULL, 0);
|
||||
Offset = DAG.getLoad(PtrVT, DAG.getEntryNode(), Offset,
|
||||
&PseudoSourceValue::getGOT(), 0);
|
||||
|
||||
// The address of the thread local variable is the add of the thread
|
||||
// pointer with the offset of the variable.
|
||||
@ -3978,7 +3990,9 @@ SDOperand X86TargetLowering::LowerSINT_TO_FP(SDOperand Op, SelectionDAG &DAG) {
|
||||
int SSFI = MF.getFrameInfo()->CreateStackObject(Size, Size);
|
||||
SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy());
|
||||
SDOperand Chain = DAG.getStore(DAG.getEntryNode(), Op.getOperand(0),
|
||||
StackSlot, NULL, 0);
|
||||
StackSlot,
|
||||
&PseudoSourceValue::getFixedStack(),
|
||||
SSFI);
|
||||
|
||||
// These are really Legal; caller falls through into that case.
|
||||
if (SrcVT == MVT::i32 && isScalarFPTypeInSSEReg(Op.getValueType()))
|
||||
@ -4019,7 +4033,8 @@ SDOperand X86TargetLowering::LowerSINT_TO_FP(SDOperand Op, SelectionDAG &DAG) {
|
||||
Ops.push_back(DAG.getValueType(Op.getValueType()));
|
||||
Ops.push_back(InFlag);
|
||||
Chain = DAG.getNode(X86ISD::FST, Tys, &Ops[0], Ops.size());
|
||||
Result = DAG.getLoad(Op.getValueType(), Chain, StackSlot, NULL, 0);
|
||||
Result = DAG.getLoad(Op.getValueType(), Chain, StackSlot,
|
||||
&PseudoSourceValue::getFixedStack(), SSFI);
|
||||
}
|
||||
|
||||
return Result;
|
||||
@ -4057,7 +4072,8 @@ FP_TO_SINTHelper(SDOperand Op, SelectionDAG &DAG) {
|
||||
SDOperand Value = Op.getOperand(0);
|
||||
if (isScalarFPTypeInSSEReg(Op.getOperand(0).getValueType())) {
|
||||
assert(Op.getValueType() == MVT::i64 && "Invalid FP_TO_SINT to lower!");
|
||||
Chain = DAG.getStore(Chain, Value, StackSlot, NULL, 0);
|
||||
Chain = DAG.getStore(Chain, Value, StackSlot,
|
||||
&PseudoSourceValue::getFixedStack(), SSFI);
|
||||
SDVTList Tys = DAG.getVTList(Op.getOperand(0).getValueType(), MVT::Other);
|
||||
SDOperand Ops[] = {
|
||||
Chain, StackSlot, DAG.getValueType(Op.getOperand(0).getValueType())
|
||||
@ -4116,7 +4132,8 @@ SDOperand X86TargetLowering::LowerFABS(SDOperand Op, SelectionDAG &DAG) {
|
||||
}
|
||||
Constant *C = ConstantVector::get(CV);
|
||||
SDOperand CPIdx = DAG.getConstantPool(C, getPointerTy(), 4);
|
||||
SDOperand Mask = DAG.getLoad(VT, DAG.getEntryNode(), CPIdx, NULL, 0,
|
||||
SDOperand Mask = DAG.getLoad(VT, DAG.getEntryNode(), CPIdx,
|
||||
&PseudoSourceValue::getConstantPool(), 0,
|
||||
false, 16);
|
||||
return DAG.getNode(X86ISD::FAND, VT, Op.getOperand(0), Mask);
|
||||
}
|
||||
@ -4144,7 +4161,8 @@ SDOperand X86TargetLowering::LowerFNEG(SDOperand Op, SelectionDAG &DAG) {
|
||||
}
|
||||
Constant *C = ConstantVector::get(CV);
|
||||
SDOperand CPIdx = DAG.getConstantPool(C, getPointerTy(), 4);
|
||||
SDOperand Mask = DAG.getLoad(VT, DAG.getEntryNode(), CPIdx, NULL, 0,
|
||||
SDOperand Mask = DAG.getLoad(VT, DAG.getEntryNode(), CPIdx,
|
||||
&PseudoSourceValue::getConstantPool(), 0,
|
||||
false, 16);
|
||||
if (MVT::isVector(VT)) {
|
||||
return DAG.getNode(ISD::BIT_CONVERT, VT,
|
||||
@ -4192,7 +4210,8 @@ SDOperand X86TargetLowering::LowerFCOPYSIGN(SDOperand Op, SelectionDAG &DAG) {
|
||||
}
|
||||
Constant *C = ConstantVector::get(CV);
|
||||
SDOperand CPIdx = DAG.getConstantPool(C, getPointerTy(), 4);
|
||||
SDOperand Mask1 = DAG.getLoad(SrcVT, DAG.getEntryNode(), CPIdx, NULL, 0,
|
||||
SDOperand Mask1 = DAG.getLoad(SrcVT, DAG.getEntryNode(), CPIdx,
|
||||
&PseudoSourceValue::getConstantPool(), 0,
|
||||
false, 16);
|
||||
SDOperand SignBit = DAG.getNode(X86ISD::FAND, SrcVT, Op1, Mask1);
|
||||
|
||||
@ -4220,7 +4239,8 @@ SDOperand X86TargetLowering::LowerFCOPYSIGN(SDOperand Op, SelectionDAG &DAG) {
|
||||
}
|
||||
C = ConstantVector::get(CV);
|
||||
CPIdx = DAG.getConstantPool(C, getPointerTy(), 4);
|
||||
SDOperand Mask2 = DAG.getLoad(VT, DAG.getEntryNode(), CPIdx, NULL, 0,
|
||||
SDOperand Mask2 = DAG.getLoad(VT, DAG.getEntryNode(), CPIdx,
|
||||
&PseudoSourceValue::getConstantPool(), 0,
|
||||
false, 16);
|
||||
SDOperand Val = DAG.getNode(X86ISD::FAND, VT, Op0, Mask2);
|
||||
|
||||
@ -4676,14 +4696,13 @@ SDNode *X86TargetLowering::ExpandREADCYCLECOUNTER(SDNode *N, SelectionDAG &DAG){
|
||||
}
|
||||
|
||||
SDOperand X86TargetLowering::LowerVASTART(SDOperand Op, SelectionDAG &DAG) {
|
||||
SrcValueSDNode *SV = cast<SrcValueSDNode>(Op.getOperand(2));
|
||||
const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
|
||||
|
||||
if (!Subtarget->is64Bit()) {
|
||||
// vastart just stores the address of the VarArgsFrameIndex slot into the
|
||||
// memory location argument.
|
||||
SDOperand FR = DAG.getFrameIndex(VarArgsFrameIndex, getPointerTy());
|
||||
return DAG.getStore(Op.getOperand(0), FR,Op.getOperand(1), SV->getValue(),
|
||||
SV->getOffset());
|
||||
return DAG.getStore(Op.getOperand(0), FR,Op.getOperand(1), SV, 0);
|
||||
}
|
||||
|
||||
// __va_list_tag:
|
||||
@ -4696,28 +4715,26 @@ SDOperand X86TargetLowering::LowerVASTART(SDOperand Op, SelectionDAG &DAG) {
|
||||
// Store gp_offset
|
||||
SDOperand Store = DAG.getStore(Op.getOperand(0),
|
||||
DAG.getConstant(VarArgsGPOffset, MVT::i32),
|
||||
FIN, SV->getValue(), SV->getOffset());
|
||||
FIN, SV, 0);
|
||||
MemOps.push_back(Store);
|
||||
|
||||
// Store fp_offset
|
||||
FIN = DAG.getNode(ISD::ADD, getPointerTy(), FIN, DAG.getIntPtrConstant(4));
|
||||
Store = DAG.getStore(Op.getOperand(0),
|
||||
DAG.getConstant(VarArgsFPOffset, MVT::i32),
|
||||
FIN, SV->getValue(), SV->getOffset());
|
||||
FIN, SV, 0);
|
||||
MemOps.push_back(Store);
|
||||
|
||||
// Store ptr to overflow_arg_area
|
||||
FIN = DAG.getNode(ISD::ADD, getPointerTy(), FIN, DAG.getIntPtrConstant(4));
|
||||
SDOperand OVFIN = DAG.getFrameIndex(VarArgsFrameIndex, getPointerTy());
|
||||
Store = DAG.getStore(Op.getOperand(0), OVFIN, FIN, SV->getValue(),
|
||||
SV->getOffset());
|
||||
Store = DAG.getStore(Op.getOperand(0), OVFIN, FIN, SV, 0);
|
||||
MemOps.push_back(Store);
|
||||
|
||||
// Store ptr to reg_save_area.
|
||||
FIN = DAG.getNode(ISD::ADD, getPointerTy(), FIN, DAG.getIntPtrConstant(8));
|
||||
SDOperand RSFIN = DAG.getFrameIndex(RegSaveFrameIndex, getPointerTy());
|
||||
Store = DAG.getStore(Op.getOperand(0), RSFIN, FIN, SV->getValue(),
|
||||
SV->getOffset());
|
||||
Store = DAG.getStore(Op.getOperand(0), RSFIN, FIN, SV, 0);
|
||||
MemOps.push_back(Store);
|
||||
return DAG.getNode(ISD::TokenFactor, MVT::Other, &MemOps[0], MemOps.size());
|
||||
}
|
||||
@ -4727,18 +4744,15 @@ SDOperand X86TargetLowering::LowerVACOPY(SDOperand Op, SelectionDAG &DAG) {
|
||||
SDOperand Chain = Op.getOperand(0);
|
||||
SDOperand DstPtr = Op.getOperand(1);
|
||||
SDOperand SrcPtr = Op.getOperand(2);
|
||||
SrcValueSDNode *DstSV = cast<SrcValueSDNode>(Op.getOperand(3));
|
||||
SrcValueSDNode *SrcSV = cast<SrcValueSDNode>(Op.getOperand(4));
|
||||
const Value *DstSV = cast<SrcValueSDNode>(Op.getOperand(3))->getValue();
|
||||
const Value *SrcSV = cast<SrcValueSDNode>(Op.getOperand(4))->getValue();
|
||||
|
||||
SrcPtr = DAG.getLoad(getPointerTy(), Chain, SrcPtr,
|
||||
SrcSV->getValue(), SrcSV->getOffset());
|
||||
SrcPtr = DAG.getLoad(getPointerTy(), Chain, SrcPtr, SrcSV, 0);
|
||||
Chain = SrcPtr.getValue(1);
|
||||
for (unsigned i = 0; i < 3; ++i) {
|
||||
SDOperand Val = DAG.getLoad(MVT::i64, Chain, SrcPtr,
|
||||
SrcSV->getValue(), SrcSV->getOffset());
|
||||
SDOperand Val = DAG.getLoad(MVT::i64, Chain, SrcPtr, SrcSV, 0);
|
||||
Chain = Val.getValue(1);
|
||||
Chain = DAG.getStore(Chain, Val, DstPtr,
|
||||
DstSV->getValue(), DstSV->getOffset());
|
||||
Chain = DAG.getStore(Chain, Val, DstPtr, DstSV, 0);
|
||||
if (i == 2)
|
||||
break;
|
||||
SrcPtr = DAG.getNode(ISD::ADD, getPointerTy(), SrcPtr,
|
||||
@ -4918,7 +4932,7 @@ SDOperand X86TargetLowering::LowerTRAMPOLINE(SDOperand Op,
|
||||
SDOperand FPtr = Op.getOperand(2); // nested function
|
||||
SDOperand Nest = Op.getOperand(3); // 'nest' parameter value
|
||||
|
||||
SrcValueSDNode *TrmpSV = cast<SrcValueSDNode>(Op.getOperand(4));
|
||||
const Value *TrmpAddr = cast<SrcValueSDNode>(Op.getOperand(4))->getValue();
|
||||
|
||||
const X86InstrInfo *TII =
|
||||
((X86TargetMachine&)getTargetMachine()).getInstrInfo();
|
||||
@ -4942,33 +4956,31 @@ SDOperand X86TargetLowering::LowerTRAMPOLINE(SDOperand Op,
|
||||
unsigned OpCode = ((MOV64ri | N86R11) << 8) | REX_WB; // movabsq r11
|
||||
SDOperand Addr = Trmp;
|
||||
OutChains[0] = DAG.getStore(Root, DAG.getConstant(OpCode, MVT::i16), Addr,
|
||||
TrmpSV->getValue(), TrmpSV->getOffset());
|
||||
TrmpAddr, 0);
|
||||
|
||||
Addr = DAG.getNode(ISD::ADD, MVT::i64, Trmp, DAG.getConstant(2, MVT::i64));
|
||||
OutChains[1] = DAG.getStore(Root, FPtr, Addr, TrmpSV->getValue(),
|
||||
TrmpSV->getOffset() + 2, false, 2);
|
||||
OutChains[1] = DAG.getStore(Root, FPtr, Addr, TrmpAddr, 2, false, 2);
|
||||
|
||||
// Load the 'nest' parameter value into R10.
|
||||
// R10 is specified in X86CallingConv.td
|
||||
OpCode = ((MOV64ri | N86R10) << 8) | REX_WB; // movabsq r10
|
||||
Addr = DAG.getNode(ISD::ADD, MVT::i64, Trmp, DAG.getConstant(10, MVT::i64));
|
||||
OutChains[2] = DAG.getStore(Root, DAG.getConstant(OpCode, MVT::i16), Addr,
|
||||
TrmpSV->getValue(), TrmpSV->getOffset() + 10);
|
||||
TrmpAddr, 10);
|
||||
|
||||
Addr = DAG.getNode(ISD::ADD, MVT::i64, Trmp, DAG.getConstant(12, MVT::i64));
|
||||
OutChains[3] = DAG.getStore(Root, Nest, Addr, TrmpSV->getValue(),
|
||||
TrmpSV->getOffset() + 12, false, 2);
|
||||
OutChains[3] = DAG.getStore(Root, Nest, Addr, TrmpAddr, 12, false, 2);
|
||||
|
||||
// Jump to the nested function.
|
||||
OpCode = (JMP64r << 8) | REX_WB; // jmpq *...
|
||||
Addr = DAG.getNode(ISD::ADD, MVT::i64, Trmp, DAG.getConstant(20, MVT::i64));
|
||||
OutChains[4] = DAG.getStore(Root, DAG.getConstant(OpCode, MVT::i16), Addr,
|
||||
TrmpSV->getValue(), TrmpSV->getOffset() + 20);
|
||||
TrmpAddr, 20);
|
||||
|
||||
unsigned char ModRM = N86R11 | (4 << 3) | (3 << 6); // ...r11
|
||||
Addr = DAG.getNode(ISD::ADD, MVT::i64, Trmp, DAG.getConstant(22, MVT::i64));
|
||||
OutChains[5] = DAG.getStore(Root, DAG.getConstant(ModRM, MVT::i8), Addr,
|
||||
TrmpSV->getValue(), TrmpSV->getOffset() + 22);
|
||||
TrmpAddr, 22);
|
||||
|
||||
SDOperand Ops[] =
|
||||
{ Trmp, DAG.getNode(ISD::TokenFactor, MVT::Other, OutChains, 6) };
|
||||
@ -5026,20 +5038,18 @@ SDOperand X86TargetLowering::LowerTRAMPOLINE(SDOperand Op,
|
||||
const unsigned char N86Reg =
|
||||
((X86RegisterInfo*)RegInfo)->getX86RegNum(NestReg);
|
||||
OutChains[0] = DAG.getStore(Root, DAG.getConstant(MOV32ri|N86Reg, MVT::i8),
|
||||
Trmp, TrmpSV->getValue(), TrmpSV->getOffset());
|
||||
Trmp, TrmpAddr, 0);
|
||||
|
||||
Addr = DAG.getNode(ISD::ADD, MVT::i32, Trmp, DAG.getConstant(1, MVT::i32));
|
||||
OutChains[1] = DAG.getStore(Root, Nest, Addr, TrmpSV->getValue(),
|
||||
TrmpSV->getOffset() + 1, false, 1);
|
||||
OutChains[1] = DAG.getStore(Root, Nest, Addr, TrmpAddr, 1, false, 1);
|
||||
|
||||
const unsigned char JMP = TII->getBaseOpcodeFor(X86::JMP);
|
||||
Addr = DAG.getNode(ISD::ADD, MVT::i32, Trmp, DAG.getConstant(5, MVT::i32));
|
||||
OutChains[2] = DAG.getStore(Root, DAG.getConstant(JMP, MVT::i8), Addr,
|
||||
TrmpSV->getValue() + 5, TrmpSV->getOffset());
|
||||
TrmpAddr, 5, false, 1);
|
||||
|
||||
Addr = DAG.getNode(ISD::ADD, MVT::i32, Trmp, DAG.getConstant(6, MVT::i32));
|
||||
OutChains[3] = DAG.getStore(Root, Disp, Addr, TrmpSV->getValue(),
|
||||
TrmpSV->getOffset() + 6, false, 1);
|
||||
OutChains[3] = DAG.getStore(Root, Disp, Addr, TrmpAddr, 6, false, 1);
|
||||
|
||||
SDOperand Ops[] =
|
||||
{ Trmp, DAG.getNode(ISD::TokenFactor, MVT::Other, OutChains, 4) };
|
||||
|
@ -313,6 +313,12 @@ private:
|
||||
std::vector<std::pair<std::string, std::string> > OrigChains;
|
||||
std::set<std::string> Duplicates;
|
||||
|
||||
/// LSI - Load/Store information.
|
||||
/// Save loads/stores matched by a pattern, and generate a MemOperandSDNode
|
||||
/// for each memory access. This facilitates the use of AliasAnalysis in
|
||||
/// the backend.
|
||||
std::vector<std::string> LSI;
|
||||
|
||||
/// GeneratedCode - This is the buffer that we emit code to. The first int
|
||||
/// indicates whether this is an exit predicate (something that should be
|
||||
/// tested, and if true, the match fails) [when 1], or normal code to emit
|
||||
@ -373,6 +379,16 @@ public:
|
||||
void EmitMatchCode(TreePatternNode *N, TreePatternNode *P,
|
||||
const std::string &RootName, const std::string &ChainSuffix,
|
||||
bool &FoundChain) {
|
||||
|
||||
// Save loads/stores matched by a pattern.
|
||||
if (!N->isLeaf() && N->getName().empty()) {
|
||||
std::string EnumName = N->getOperator()->getValueAsString("Opcode");
|
||||
if (EnumName == "ISD::LOAD" ||
|
||||
EnumName == "ISD::STORE") {
|
||||
LSI.push_back(RootName);
|
||||
}
|
||||
}
|
||||
|
||||
bool isRoot = (P == NULL);
|
||||
// Emit instruction predicates. Each predicate is just a string for now.
|
||||
if (isRoot) {
|
||||
@ -944,6 +960,18 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
// Generate MemOperandSDNodes nodes for each memory accesses covered by this
|
||||
// pattern.
|
||||
if (isRoot) {
|
||||
std::vector<std::string>::const_iterator mi, mie;
|
||||
for (mi = LSI.begin(), mie = LSI.end(); mi != mie; ++mi) {
|
||||
emitCode("SDOperand LSI_" + *mi + " = "
|
||||
"CurDAG->getMemOperand(cast<LSBaseSDNode>(" +
|
||||
*mi + ")->getMemOperand());");
|
||||
AllOps.push_back("LSI_" + *mi);
|
||||
}
|
||||
}
|
||||
|
||||
// Emit all the chain and CopyToReg stuff.
|
||||
bool ChainEmitted = NodeHasChain;
|
||||
if (NodeHasChain)
|
||||
|
Loading…
x
Reference in New Issue
Block a user