Refactoring of formal parameter flags. Enable properly use of

zext/sext/aext stuff.

llvm-svn: 35008
This commit is contained in:
Anton Korobeynikov 2007-03-07 16:25:09 +00:00
parent dd6ce6900e
commit ed4b303c10
12 changed files with 73 additions and 72 deletions

View File

@ -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 {

View File

@ -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.

View File

@ -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>

View File

@ -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());

View File

@ -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?");

View File

@ -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;

View File

@ -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:

View File

@ -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
}

View File

@ -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
}

View File

@ -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

View File

@ -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);

View File

@ -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!";