forked from OSchip/llvm-project
Refactoring of formal parameter flags. Enable properly use of
zext/sext/aext stuff. llvm-svn: 35008
This commit is contained in:
parent
dd6ce6900e
commit
ed4b303c10
|
@ -30,21 +30,7 @@ namespace llvm {
|
|||
class TargetLowering;
|
||||
class FunctionLoweringInfo;
|
||||
class HazardRecognizer;
|
||||
|
||||
namespace SDISelParamFlags {
|
||||
enum Flags {
|
||||
NoFlagSet = 0,
|
||||
Signed = 1<<0,
|
||||
SignedOffs = 0,
|
||||
InReg = 1<<1,
|
||||
InRegOffs = 1,
|
||||
StructReturn = 1<<2,
|
||||
StructReturnOffs = 2,
|
||||
OrigAlignment = 0x1F<<27,
|
||||
OrigAlignmentOffs = 27
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/// SelectionDAGISel - This is the common base class used for SelectionDAG-based
|
||||
/// pattern-matching instruction selectors.
|
||||
class SelectionDAGISel : public FunctionPass {
|
||||
|
|
|
@ -48,11 +48,26 @@ struct SDVTList {
|
|||
unsigned short NumVTs;
|
||||
};
|
||||
|
||||
|
||||
/// ISD namespace - This namespace contains an enum which represents all of the
|
||||
/// SelectionDAG node types and value types.
|
||||
///
|
||||
namespace ISD {
|
||||
namespace ParamFlags {
|
||||
enum Flags {
|
||||
NoFlagSet = 0,
|
||||
ZExt = 1<<0, ///< Parameter should be zero extended
|
||||
ZExtOffs = 0,
|
||||
SExt = 1<<1, ///< Parameter should be sign extended
|
||||
SExtOffs = 1,
|
||||
InReg = 1<<2, ///< Parameter should be passed in register
|
||||
InRegOffs = 2,
|
||||
StructReturn = 1<<3, ///< Hidden struct-return pointer
|
||||
StructReturnOffs = 3,
|
||||
OrigAlignment = 0x1F<<27,
|
||||
OrigAlignmentOffs = 27
|
||||
};
|
||||
}
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
/// ISD::NodeType enum - This enum defines all of the operators valid in a
|
||||
/// SelectionDAG.
|
||||
|
|
|
@ -765,11 +765,12 @@ public:
|
|||
struct ArgListEntry {
|
||||
SDOperand Node;
|
||||
const Type* Ty;
|
||||
bool isSigned;
|
||||
bool isSExt;
|
||||
bool isZExt;
|
||||
bool isInReg;
|
||||
bool isSRet;
|
||||
|
||||
ArgListEntry():isSigned(false), isInReg(false), isSRet(false) { };
|
||||
ArgListEntry():isSExt(false), isZExt(false), isInReg(false), isSRet(false) { };
|
||||
};
|
||||
typedef std::vector<ArgListEntry> ArgListTy;
|
||||
virtual std::pair<SDOperand, SDOperand>
|
||||
|
|
|
@ -2242,8 +2242,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
|
|||
|
||||
const char *FnName = 0;
|
||||
if (Node->getOpcode() == ISD::MEMSET) {
|
||||
Entry.Node = Tmp2; Entry.isSigned = false; Entry.Ty = IntPtrTy;
|
||||
Entry.isInReg = false; Entry.isSRet = false;
|
||||
Entry.Node = Tmp2; Entry.Ty = IntPtrTy;
|
||||
Args.push_back(Entry);
|
||||
// Extend the (previously legalized) ubyte argument to be an int value
|
||||
// for the call.
|
||||
|
@ -2251,17 +2250,15 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
|
|||
Tmp3 = DAG.getNode(ISD::TRUNCATE, MVT::i32, Tmp3);
|
||||
else
|
||||
Tmp3 = DAG.getNode(ISD::ZERO_EXTEND, MVT::i32, Tmp3);
|
||||
Entry.Node = Tmp3; Entry.Ty = Type::Int32Ty; Entry.isSigned = true;
|
||||
Entry.isInReg = false; Entry.isSRet = false;
|
||||
Entry.Node = Tmp3; Entry.Ty = Type::Int32Ty; Entry.isSExt = true;
|
||||
Args.push_back(Entry);
|
||||
Entry.Node = Tmp4; Entry.Ty = IntPtrTy; Entry.isSigned = false;
|
||||
Entry.Node = Tmp4; Entry.Ty = IntPtrTy; Entry.isSExt = false;
|
||||
Args.push_back(Entry);
|
||||
|
||||
FnName = "memset";
|
||||
} else if (Node->getOpcode() == ISD::MEMCPY ||
|
||||
Node->getOpcode() == ISD::MEMMOVE) {
|
||||
Entry.Ty = IntPtrTy;
|
||||
Entry.isSigned = false; Entry.isInReg = false; Entry.isSRet = false;
|
||||
Entry.Node = Tmp2; Args.push_back(Entry);
|
||||
Entry.Node = Tmp3; Args.push_back(Entry);
|
||||
Entry.Node = Tmp4; Args.push_back(Entry);
|
||||
|
@ -4228,7 +4225,7 @@ SDOperand SelectionDAGLegalize::ExpandLibCall(const char *Name, SDNode *Node,
|
|||
MVT::ValueType ArgVT = Node->getOperand(i).getValueType();
|
||||
const Type *ArgTy = MVT::getTypeForValueType(ArgVT);
|
||||
Entry.Node = Node->getOperand(i); Entry.Ty = ArgTy;
|
||||
Entry.isSigned = isSigned; Entry.isInReg = false; Entry.isSRet = false;
|
||||
Entry.isSExt = isSigned;
|
||||
Args.push_back(Entry);
|
||||
}
|
||||
SDOperand Callee = DAG.getExternalSymbol(Name, TLI.getPointerTy());
|
||||
|
|
|
@ -2279,7 +2279,8 @@ void SelectionDAGLowering::LowerCallTo(Instruction &I,
|
|||
Value *Arg = I.getOperand(i);
|
||||
SDOperand ArgNode = getValue(Arg);
|
||||
Entry.Node = ArgNode; Entry.Ty = Arg->getType();
|
||||
Entry.isSigned = FTy->paramHasAttr(i, FunctionType::SExtAttribute);
|
||||
Entry.isSExt = FTy->paramHasAttr(i, FunctionType::SExtAttribute);
|
||||
Entry.isZExt = FTy->paramHasAttr(i, FunctionType::ZExtAttribute);
|
||||
Entry.isInReg = FTy->paramHasAttr(i, FunctionType::InRegAttribute);
|
||||
Entry.isSRet = FTy->paramHasAttr(i, FunctionType::StructRetAttribute);
|
||||
Args.push_back(Entry);
|
||||
|
@ -2983,9 +2984,6 @@ void SelectionDAGLowering::visitMalloc(MallocInst &I) {
|
|||
TargetLowering::ArgListEntry Entry;
|
||||
Entry.Node = Src;
|
||||
Entry.Ty = TLI.getTargetData()->getIntPtrType();
|
||||
Entry.isSigned = false;
|
||||
Entry.isInReg = false;
|
||||
Entry.isSRet = false;
|
||||
Args.push_back(Entry);
|
||||
|
||||
std::pair<SDOperand,SDOperand> Result =
|
||||
|
@ -3001,9 +2999,6 @@ void SelectionDAGLowering::visitFree(FreeInst &I) {
|
|||
TargetLowering::ArgListEntry Entry;
|
||||
Entry.Node = getValue(I.getOperand(0));
|
||||
Entry.Ty = TLI.getTargetData()->getIntPtrType();
|
||||
Entry.isSigned = false;
|
||||
Entry.isInReg = false;
|
||||
Entry.isSRet = false;
|
||||
Args.push_back(Entry);
|
||||
MVT::ValueType IntPtr = TLI.getPointerTy();
|
||||
std::pair<SDOperand,SDOperand> Result =
|
||||
|
@ -3099,21 +3094,21 @@ TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
|
|||
for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end();
|
||||
I != E; ++I, ++j) {
|
||||
MVT::ValueType VT = getValueType(I->getType());
|
||||
unsigned Flags = SDISelParamFlags::NoFlagSet;
|
||||
unsigned Flags = ISD::ParamFlags::NoFlagSet;
|
||||
unsigned OriginalAlignment =
|
||||
getTargetData()->getABITypeAlignment(I->getType());
|
||||
|
||||
// FIXME: Distinguish between a formal with no [sz]ext attribute from one
|
||||
// that is zero extended!
|
||||
if (FTy->paramHasAttr(j, FunctionType::ZExtAttribute))
|
||||
Flags &= ~(SDISelParamFlags::Signed);
|
||||
Flags &= ~(ISD::ParamFlags::SExt);
|
||||
if (FTy->paramHasAttr(j, FunctionType::SExtAttribute))
|
||||
Flags |= SDISelParamFlags::Signed;
|
||||
Flags |= ISD::ParamFlags::SExt;
|
||||
if (FTy->paramHasAttr(j, FunctionType::InRegAttribute))
|
||||
Flags |= SDISelParamFlags::InReg;
|
||||
Flags |= ISD::ParamFlags::InReg;
|
||||
if (FTy->paramHasAttr(j, FunctionType::StructRetAttribute))
|
||||
Flags |= SDISelParamFlags::StructReturn;
|
||||
Flags |= (OriginalAlignment << SDISelParamFlags::OrigAlignmentOffs);
|
||||
Flags |= ISD::ParamFlags::StructReturn;
|
||||
Flags |= (OriginalAlignment << ISD::ParamFlags::OrigAlignmentOffs);
|
||||
|
||||
switch (getTypeAction(VT)) {
|
||||
default: assert(0 && "Unknown type action!");
|
||||
|
@ -3136,8 +3131,8 @@ TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
|
|||
RetVals.push_back(NVT);
|
||||
// if it isn't first piece, alignment must be 1
|
||||
if (i > 0)
|
||||
Flags = (Flags & (~SDISelParamFlags::OrigAlignment)) |
|
||||
(1 << SDISelParamFlags::OrigAlignmentOffs);
|
||||
Flags = (Flags & (~ISD::ParamFlags::OrigAlignment)) |
|
||||
(1 << ISD::ParamFlags::OrigAlignmentOffs);
|
||||
Ops.push_back(DAG.getConstant(Flags, MVT::i32));
|
||||
}
|
||||
} else {
|
||||
|
@ -3246,8 +3241,8 @@ static void ExpandScalarCallArgs(MVT::ValueType VT, SDOperand Arg,
|
|||
if (TLI.getTypeAction(VT) != TargetLowering::Expand) {
|
||||
// if it isn't first piece, alignment must be 1
|
||||
if (!isFirst)
|
||||
Flags = (Flags & (~SDISelParamFlags::OrigAlignment)) |
|
||||
(1 << SDISelParamFlags::OrigAlignmentOffs);
|
||||
Flags = (Flags & (~ISD::ParamFlags::OrigAlignment)) |
|
||||
(1 << ISD::ParamFlags::OrigAlignmentOffs);
|
||||
Ops.push_back(Arg);
|
||||
Ops.push_back(DAG.getConstant(Flags, MVT::i32));
|
||||
return;
|
||||
|
@ -3294,17 +3289,19 @@ TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy,
|
|||
for (unsigned i = 0, e = Args.size(); i != e; ++i) {
|
||||
MVT::ValueType VT = getValueType(Args[i].Ty);
|
||||
SDOperand Op = Args[i].Node;
|
||||
unsigned Flags = SDISelParamFlags::NoFlagSet;
|
||||
unsigned Flags = ISD::ParamFlags::NoFlagSet;
|
||||
unsigned OriginalAlignment =
|
||||
getTargetData()->getABITypeAlignment(Args[i].Ty);
|
||||
|
||||
if (Args[i].isSigned)
|
||||
Flags |= SDISelParamFlags::Signed;
|
||||
if (Args[i].isSExt)
|
||||
Flags |= ISD::ParamFlags::SExt;
|
||||
if (Args[i].isZExt)
|
||||
Flags |= ISD::ParamFlags::ZExt;
|
||||
if (Args[i].isInReg)
|
||||
Flags |= SDISelParamFlags::InReg;
|
||||
Flags |= ISD::ParamFlags::InReg;
|
||||
if (Args[i].isSRet)
|
||||
Flags |= SDISelParamFlags::StructReturn;
|
||||
Flags |= OriginalAlignment << SDISelParamFlags::OrigAlignmentOffs;
|
||||
Flags |= ISD::ParamFlags::StructReturn;
|
||||
Flags |= OriginalAlignment << ISD::ParamFlags::OrigAlignmentOffs;
|
||||
|
||||
switch (getTypeAction(VT)) {
|
||||
default: assert(0 && "Unknown type action!");
|
||||
|
@ -3314,7 +3311,13 @@ TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy,
|
|||
break;
|
||||
case Promote:
|
||||
if (MVT::isInteger(VT)) {
|
||||
unsigned ExtOp = Args[i].isSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND;
|
||||
unsigned ExtOp;
|
||||
if (Args[i].isSExt)
|
||||
ExtOp = ISD::SIGN_EXTEND;
|
||||
else if (Args[i].isZExt)
|
||||
ExtOp = ISD::ZERO_EXTEND;
|
||||
else
|
||||
ExtOp = ISD::ANY_EXTEND;
|
||||
Op = DAG.getNode(ExtOp, getTypeToTransformTo(VT), Op);
|
||||
} else {
|
||||
assert(MVT::isFloatingPoint(VT) && "Not int or FP?");
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
#include "llvm/CodeGen/MachineFunction.h"
|
||||
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||
#include "llvm/CodeGen/SelectionDAG.h"
|
||||
#include "llvm/CodeGen/SelectionDAGISel.h"
|
||||
#include "llvm/CodeGen/SSARegMap.h"
|
||||
#include "llvm/Target/TargetOptions.h"
|
||||
#include "llvm/ADT/VectorExtras.h"
|
||||
|
@ -347,7 +346,7 @@ HowToPassArgument(MVT::ValueType ObjectVT, unsigned NumGPRs,
|
|||
NeededGPRs = 0;
|
||||
StackPad = 0;
|
||||
GPRPad = 0;
|
||||
unsigned align = (Flags >> SDISelParamFlags::OrigAlignmentOffs);
|
||||
unsigned align = (Flags >> ISD::ParamFlags::OrigAlignmentOffs);
|
||||
GPRPad = NumGPRs % ((align + 3)/4);
|
||||
StackPad = StackOffset % align;
|
||||
unsigned firstGPR = NumGPRs + GPRPad;
|
||||
|
|
|
@ -337,10 +337,12 @@ AlphaTargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy,
|
|||
case MVT::i32:
|
||||
// Promote the integer to 64 bits. If the input type is signed use a
|
||||
// sign extend, otherwise use a zero extend.
|
||||
if (Args[i].isSigned)
|
||||
if (Args[i].isSExt)
|
||||
Args[i].Node = DAG.getNode(ISD::SIGN_EXTEND, MVT::i64, Args[i].Node);
|
||||
else
|
||||
else if (Args[i].isZExt)
|
||||
Args[i].Node = DAG.getNode(ISD::ZERO_EXTEND, MVT::i64, Args[i].Node);
|
||||
else
|
||||
Args[i].Node = DAG.getNode(ISD::ANY_EXTEND, MVT::i64, Args[i].Node);
|
||||
break;
|
||||
case MVT::i64:
|
||||
case MVT::f64:
|
||||
|
|
|
@ -341,9 +341,11 @@ IA64TargetLowering::LowerCallTo(SDOperand Chain,
|
|||
case MVT::i32: {
|
||||
//promote to 64-bits, sign/zero extending based on type
|
||||
//of the argument
|
||||
ISD::NodeType ExtendKind = ISD::ZERO_EXTEND;
|
||||
if (Args[i].isSigned)
|
||||
ISD::NodeType ExtendKind = ISD::ANY_EXTEND;
|
||||
if (Args[i].isSExt)
|
||||
ExtendKind = ISD::SIGN_EXTEND;
|
||||
else if (Args[i].isZExt)
|
||||
ExtendKind = ISD::ZERO_EXTEND;
|
||||
Val = DAG.getNode(ExtendKind, MVT::i64, Val);
|
||||
// XXX: fall through
|
||||
}
|
||||
|
|
|
@ -516,9 +516,11 @@ SparcTargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy,
|
|||
case MVT::i16: {
|
||||
// Promote the integer to 32-bits. If the input type is signed, use a
|
||||
// sign extend, otherwise use a zero extend.
|
||||
ISD::NodeType ExtendKind = ISD::ZERO_EXTEND;
|
||||
if (Args[i].isSigned)
|
||||
ISD::NodeType ExtendKind = ISD::ANY_EXTEND;
|
||||
if (Args[i].isSExt)
|
||||
ExtendKind = ISD::SIGN_EXTEND;
|
||||
else if (Args[i].isZExt)
|
||||
ExtendKind = ISD::ZERO_EXTEND;
|
||||
Val = DAG.getNode(ExtendKind, MVT::i32, Val);
|
||||
// FALL THROUGH
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ class CCIfCC<string CC, CCAction A>
|
|||
|
||||
/// CCIfInReg - If this argument is marked with the 'inreg' attribute, apply
|
||||
/// the specified action.
|
||||
class CCIfInReg<CCAction A> : CCIf<"ArgFlags & SDISelParamFlags::InReg", A> {}
|
||||
class CCIfInReg<CCAction A> : CCIf<"ArgFlags & ISD::ParamFlags::InReg", A> {}
|
||||
|
||||
|
||||
/// CCAssignToReg - This action matches if there is a register in the specified
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
#include "llvm/CodeGen/MachineFunction.h"
|
||||
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||
#include "llvm/CodeGen/SelectionDAG.h"
|
||||
#include "llvm/CodeGen/SelectionDAGISel.h"
|
||||
#include "llvm/CodeGen/SSARegMap.h"
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
#include "llvm/Target/TargetOptions.h"
|
||||
|
@ -677,7 +676,7 @@ SDOperand X86TargetLowering::LowerCCCArguments(SDOperand Op, SelectionDAG &DAG,
|
|||
// If this is an sret function, the return should pop the hidden pointer.
|
||||
if (NumArgs &&
|
||||
(cast<ConstantSDNode>(Op.getOperand(3))->getValue() &
|
||||
SDISelParamFlags::StructReturn))
|
||||
ISD::ParamFlags::StructReturn))
|
||||
BytesToPopOnReturn = 4;
|
||||
|
||||
BytesCallerReserves = StackSize;
|
||||
|
@ -751,7 +750,7 @@ SDOperand X86TargetLowering::LowerCCCCallTo(SDOperand Op, SelectionDAG &DAG,
|
|||
// If the first argument is an sret pointer, remember it.
|
||||
bool isSRet = NumOps &&
|
||||
(cast<ConstantSDNode>(Op.getOperand(6))->getValue() &
|
||||
SDISelParamFlags::StructReturn);
|
||||
ISD::ParamFlags::StructReturn);
|
||||
|
||||
if (!MemOpChains.empty())
|
||||
Chain = DAG.getNode(ISD::TokenFactor, MVT::Other,
|
||||
|
@ -3408,16 +3407,10 @@ SDOperand X86TargetLowering::LowerMEMSET(SDOperand Op, SelectionDAG &DAG) {
|
|||
TargetLowering::ArgListEntry Entry;
|
||||
Entry.Node = Op.getOperand(1);
|
||||
Entry.Ty = IntPtrTy;
|
||||
Entry.isSigned = false;
|
||||
Entry.isInReg = false;
|
||||
Entry.isSRet = false;
|
||||
Args.push_back(Entry);
|
||||
// Extend the unsigned i8 argument to be an int value for the call.
|
||||
Entry.Node = DAG.getNode(ISD::ZERO_EXTEND, MVT::i32, Op.getOperand(2));
|
||||
Entry.Ty = IntPtrTy;
|
||||
Entry.isSigned = false;
|
||||
Entry.isInReg = false;
|
||||
Entry.isSRet = false;
|
||||
Args.push_back(Entry);
|
||||
Entry.Node = Op.getOperand(3);
|
||||
Args.push_back(Entry);
|
||||
|
@ -3568,9 +3561,6 @@ SDOperand X86TargetLowering::LowerMEMCPY(SDOperand Op, SelectionDAG &DAG) {
|
|||
TargetLowering::ArgListTy Args;
|
||||
TargetLowering::ArgListEntry Entry;
|
||||
Entry.Ty = getTargetData()->getIntPtrType();
|
||||
Entry.isSigned = false;
|
||||
Entry.isInReg = false;
|
||||
Entry.isSRet = false;
|
||||
Entry.Node = Op.getOperand(1); Args.push_back(Entry);
|
||||
Entry.Node = Op.getOperand(2); Args.push_back(Entry);
|
||||
Entry.Node = Op.getOperand(3); Args.push_back(Entry);
|
||||
|
|
|
@ -123,8 +123,12 @@ void CallingConvEmitter::EmitAction(Record *Action,
|
|||
} else if (Action->isSubClassOf("CCPromoteToType")) {
|
||||
Record *DestTy = Action->getValueAsDef("DestTy");
|
||||
O << IndentStr << "LocVT = " << getEnumName(getValueType(DestTy)) <<";\n";
|
||||
O << IndentStr << "LocInfo = (ArgFlags & SDISelParamFlags::Signed) ? \n"
|
||||
<< IndentStr << IndentStr << "CCValAssign::SExt : CCValAssign::ZExt;\n";
|
||||
O << IndentStr << "if (ArgFlags & ISD::ParamFlags::SExt)\n"
|
||||
<< IndentStr << IndentStr << "LocInfo = CCValAssign::SExt;\n"
|
||||
<< IndentStr << "else if (ArgFlags & ISD::ParamFlags::ZExt)\n"
|
||||
<< IndentStr << IndentStr << "LocInfo = CCValAssign::ZExt;\n"
|
||||
<< IndentStr << "else\n"
|
||||
<< IndentStr << IndentStr << "LocInfo = CCValAssign::AExt;\n";
|
||||
} else {
|
||||
Action->dump();
|
||||
throw "Unknown CCAction!";
|
||||
|
|
Loading…
Reference in New Issue