aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen')
-rw-r--r--lib/CodeGen/SelectionDAG/CallingConvLower.cpp25
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeDAG.cpp1
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAG.cpp44
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp74
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp2
5 files changed, 90 insertions, 56 deletions
diff --git a/lib/CodeGen/SelectionDAG/CallingConvLower.cpp b/lib/CodeGen/SelectionDAG/CallingConvLower.cpp
index 6b9b31b548..667870d452 100644
--- a/lib/CodeGen/SelectionDAG/CallingConvLower.cpp
+++ b/lib/CodeGen/SelectionDAG/CallingConvLower.cpp
@@ -35,11 +35,9 @@ CCState::CCState(unsigned CC, bool isVarArg, const TargetMachine &tm,
void CCState::HandleByVal(unsigned ValNo, MVT::ValueType ValVT,
MVT::ValueType LocVT, CCValAssign::LocInfo LocInfo,
int MinSize, int MinAlign,
- ISD::ParamFlags::ParamFlagsTy ArgFlags) {
- unsigned Align = 1 << ((ArgFlags & ISD::ParamFlags::ByValAlign) >>
- ISD::ParamFlags::ByValAlignOffs);
- unsigned Size = (ArgFlags & ISD::ParamFlags::ByValSize) >>
- ISD::ParamFlags::ByValSizeOffs;
+ ISD::ArgFlagsTy ArgFlags) {
+ unsigned Align = ArgFlags.getByValAlign();
+ unsigned Size = ArgFlags.getByValSize();
if (MinSize > (int)Size)
Size = MinSize;
if (MinAlign > (int)Align)
@@ -65,9 +63,8 @@ void CCState::AnalyzeFormalArguments(SDNode *TheArgs, CCAssignFn Fn) {
for (unsigned i = 0; i != NumArgs; ++i) {
MVT::ValueType ArgVT = TheArgs->getValueType(i);
- SDOperand FlagOp = TheArgs->getOperand(3+i);
- ISD::ParamFlags::ParamFlagsTy ArgFlags =
- cast<ConstantSDNode>(FlagOp)->getValue();
+ ISD::ArgFlagsTy ArgFlags =
+ cast<ARG_FLAGSSDNode>(TheArgs->getOperand(3+i))->getArgFlags();
if (Fn(i, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, *this)) {
cerr << "Formal argument #" << i << " has unhandled type "
<< MVT::getValueTypeString(ArgVT) << "\n";
@@ -82,8 +79,9 @@ void CCState::AnalyzeReturn(SDNode *TheRet, CCAssignFn Fn) {
// Determine which register each value should be copied into.
for (unsigned i = 0, e = TheRet->getNumOperands() / 2; i != e; ++i) {
MVT::ValueType VT = TheRet->getOperand(i*2+1).getValueType();
- if (Fn(i, VT, VT, CCValAssign::Full,
- cast<ConstantSDNode>(TheRet->getOperand(i*2+2))->getValue(), *this)){
+ ISD::ArgFlagsTy ArgFlags =
+ cast<ARG_FLAGSSDNode>(TheRet->getOperand(i*2+2))->getArgFlags();
+ if (Fn(i, VT, VT, CCValAssign::Full, ArgFlags, *this)){
cerr << "Return operand #" << i << " has unhandled type "
<< MVT::getValueTypeString(VT) << "\n";
abort();
@@ -98,9 +96,8 @@ void CCState::AnalyzeCallOperands(SDNode *TheCall, CCAssignFn Fn) {
unsigned NumOps = (TheCall->getNumOperands() - 5) / 2;
for (unsigned i = 0; i != NumOps; ++i) {
MVT::ValueType ArgVT = TheCall->getOperand(5+2*i).getValueType();
- SDOperand FlagOp = TheCall->getOperand(5+2*i+1);
- ISD::ParamFlags::ParamFlagsTy ArgFlags =
- cast<ConstantSDNode>(FlagOp)->getValue();
+ ISD::ArgFlagsTy ArgFlags =
+ cast<ARG_FLAGSSDNode>(TheCall->getOperand(5+2*i+1))->getArgFlags();
if (Fn(i, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, *this)) {
cerr << "Call operand #" << i << " has unhandled type "
<< MVT::getValueTypeString(ArgVT) << "\n";
@@ -114,7 +111,7 @@ void CCState::AnalyzeCallOperands(SDNode *TheCall, CCAssignFn Fn) {
void CCState::AnalyzeCallResult(SDNode *TheCall, CCAssignFn Fn) {
for (unsigned i = 0, e = TheCall->getNumValues() - 1; i != e; ++i) {
MVT::ValueType VT = TheCall->getValueType(i);
- if (Fn(i, VT, VT, CCValAssign::Full, 0, *this)) {
+ if (Fn(i, VT, VT, CCValAssign::Full, ISD::ArgFlagsTy(), *this)) {
cerr << "Call result #" << i << " has unhandled type "
<< MVT::getValueTypeString(VT) << "\n";
abort();
diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index 56ac37590b..d318cb4372 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -808,6 +808,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
case ISD::MEMOPERAND:
case ISD::STRING:
case ISD::CONDCODE:
+ case ISD::ARG_FLAGS:
// Primitives must all be legal.
assert(TLI.isOperationLegal(Node->getOpcode(), Node->getValueType(0)) &&
"This must be legal!");
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 3cd731073c..9331e8b7ee 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -355,6 +355,9 @@ static void AddNodeIDNode(FoldingSetNodeID &ID, SDNode *N) {
// Handle SDNode leafs with special info.
switch (N->getOpcode()) {
default: break; // Normal nodes don't need extra info.
+ case ISD::ARG_FLAGS:
+ ID.AddInteger(cast<ARG_FLAGSSDNode>(N)->getArgFlags().getRawBits());
+ break;
case ISD::TargetConstant:
case ISD::Constant:
ID.Add(cast<ConstantSDNode>(N)->getAPIntValue());
@@ -923,6 +926,19 @@ SDOperand SelectionDAG::getBasicBlock(MachineBasicBlock *MBB) {
return SDOperand(N, 0);
}
+SDOperand SelectionDAG::getArgFlags(ISD::ArgFlagsTy Flags) {
+ FoldingSetNodeID ID;
+ AddNodeIDNode(ID, ISD::ARG_FLAGS, getVTList(MVT::Other), 0, 0);
+ ID.AddInteger(Flags.getRawBits());
+ void *IP = 0;
+ if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
+ return SDOperand(E, 0);
+ SDNode *N = new ARG_FLAGSSDNode(Flags);
+ CSEMap.InsertNode(N, IP);
+ AllNodes.push_back(N);
+ return SDOperand(N, 0);
+}
+
SDOperand SelectionDAG::getValueType(MVT::ValueType VT) {
if (!MVT::isExtendedVT(VT) && (unsigned)VT >= ValueTypeNodes.size())
ValueTypeNodes.resize(VT+1);
@@ -3584,6 +3600,7 @@ void MemOperandSDNode::ANCHOR() {}
void RegisterSDNode::ANCHOR() {}
void ExternalSymbolSDNode::ANCHOR() {}
void CondCodeSDNode::ANCHOR() {}
+void ARG_FLAGSSDNode::ANCHOR() {}
void VTSDNode::ANCHOR() {}
void LoadSDNode::ANCHOR() {}
void StoreSDNode::ANCHOR() {}
@@ -3831,6 +3848,7 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const {
case ISD::STRING: return "String";
case ISD::BasicBlock: return "BasicBlock";
+ case ISD::ARG_FLAGS: return "ArgFlags";
case ISD::VALUETYPE: return "ValueType";
case ISD::Register: return "Register";
@@ -4043,6 +4061,30 @@ const char *SDNode::getIndexedModeName(ISD::MemIndexedMode AM) {
}
}
+std::string ISD::ArgFlagsTy::getArgFlagsString() {
+ std::string S = "< ";
+
+ if (isZExt())
+ S += "zext ";
+ if (isSExt())
+ S += "sext ";
+ if (isInReg())
+ S += "inreg ";
+ if (isSRet())
+ S += "sret ";
+ if (isByVal())
+ S += "byval ";
+ if (isNest())
+ S += "nest ";
+ if (getByValAlign())
+ S += "byval-align:" + utostr(getByValAlign()) + " ";
+ if (getOrigAlign())
+ S += "orig-align:" + utostr(getOrigAlign()) + " ";
+ if (getByValSize())
+ S += "byval-size:" + utostr(getByValSize()) + " ";
+ return S + ">";
+}
+
void SDNode::dump() const { dump(0); }
void SDNode::dump(const SelectionDAG *G) const {
cerr << (void*)this << ": ";
@@ -4138,6 +4180,8 @@ void SDNode::dump(const SelectionDAG *G) const {
cerr << "<" << M->MO.getValue() << ":" << M->MO.getOffset() << ">";
else
cerr << "<null:" << M->MO.getOffset() << ">";
+ } else if (const ARG_FLAGSSDNode *N = dyn_cast<ARG_FLAGSSDNode>(this)) {
+ cerr << N->getArgFlags().getArgFlagsString();
} else if (const VTSDNode *N = dyn_cast<VTSDNode>(this)) {
cerr << ":" << MVT::getValueTypeString(N->getVT());
} else if (const LoadSDNode *LD = dyn_cast<LoadSDNode>(this)) {
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index 1e249d0386..d9d58fa037 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -1064,7 +1064,7 @@ void SelectionDAGLowering::visitRet(ReturnInst &I) {
for (unsigned i = 0; i < NumParts; ++i) {
NewValues.push_back(Parts[i]);
- NewValues.push_back(DAG.getConstant(false, MVT::i32));
+ NewValues.push_back(DAG.getArgFlags(ISD::ArgFlagsTy()));
}
}
DAG.setRoot(DAG.getNode(ISD::RET, MVT::Other,
@@ -4065,39 +4065,34 @@ 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());
- ISD::ParamFlags::ParamFlagsTy Flags = ISD::ParamFlags::NoFlagSet;
+ ISD::ArgFlagsTy Flags;
unsigned OriginalAlignment =
getTargetData()->getABITypeAlignment(I->getType());
- // FIXME: Distinguish between a formal with no [sz]ext attribute from one
- // that is zero extended!
if (F.paramHasAttr(j, ParamAttr::ZExt))
- Flags &= ~(ISD::ParamFlags::SExt);
+ Flags.setZExt();
if (F.paramHasAttr(j, ParamAttr::SExt))
- Flags |= ISD::ParamFlags::SExt;
+ Flags.setSExt();
if (F.paramHasAttr(j, ParamAttr::InReg))
- Flags |= ISD::ParamFlags::InReg;
+ Flags.setInReg();
if (F.paramHasAttr(j, ParamAttr::StructRet))
- Flags |= ISD::ParamFlags::StructReturn;
+ Flags.setSRet();
if (F.paramHasAttr(j, ParamAttr::ByVal)) {
- Flags |= ISD::ParamFlags::ByVal;
+ Flags.setByVal();
const PointerType *Ty = cast<PointerType>(I->getType());
const Type *ElementTy = Ty->getElementType();
- unsigned FrameAlign = Log2_32(getByValTypeAlignment(ElementTy));
+ unsigned FrameAlign = getByValTypeAlignment(ElementTy);
unsigned FrameSize = getTargetData()->getABITypeSize(ElementTy);
// For ByVal, alignment should be passed from FE. BE will guess if
// this info is not there but there are cases it cannot get right.
if (F.getParamAlignment(j))
- FrameAlign = Log2_32(F.getParamAlignment(j));
- Flags |= ((ISD::ParamFlags::ParamFlagsTy)FrameAlign
- << ISD::ParamFlags::ByValAlignOffs);
- Flags |= ((ISD::ParamFlags::ParamFlagsTy)FrameSize
- << ISD::ParamFlags::ByValSizeOffs);
+ FrameAlign = F.getParamAlignment(j);
+ Flags.setByValAlign(FrameAlign);
+ Flags.setByValSize(FrameSize);
}
if (F.paramHasAttr(j, ParamAttr::Nest))
- Flags |= ISD::ParamFlags::Nest;
- Flags |= ((ISD::ParamFlags::ParamFlagsTy)OriginalAlignment
- << ISD::ParamFlags::OrigAlignmentOffs);
+ Flags.setNest();
+ Flags.setOrigAlign(OriginalAlignment);
MVT::ValueType RegisterVT = getRegisterType(VT);
unsigned NumRegs = getNumRegisters(VT);
@@ -4105,9 +4100,8 @@ TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
RetVals.push_back(RegisterVT);
// if it isn't first piece, alignment must be 1
if (i > 0)
- Flags = (Flags & (~ISD::ParamFlags::OrigAlignment)) |
- (ISD::ParamFlags::One << ISD::ParamFlags::OrigAlignmentOffs);
- Ops.push_back(DAG.getConstant(Flags, MVT::i64));
+ Flags.setOrigAlign(1);
+ Ops.push_back(DAG.getArgFlags(Flags));
}
}
@@ -4183,37 +4177,34 @@ 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;
- ISD::ParamFlags::ParamFlagsTy Flags = ISD::ParamFlags::NoFlagSet;
+ ISD::ArgFlagsTy Flags;
unsigned OriginalAlignment =
getTargetData()->getABITypeAlignment(Args[i].Ty);
-
- if (Args[i].isSExt)
- Flags |= ISD::ParamFlags::SExt;
+
if (Args[i].isZExt)
- Flags |= ISD::ParamFlags::ZExt;
+ Flags.setZExt();
+ if (Args[i].isSExt)
+ Flags.setSExt();
if (Args[i].isInReg)
- Flags |= ISD::ParamFlags::InReg;
+ Flags.setInReg();
if (Args[i].isSRet)
- Flags |= ISD::ParamFlags::StructReturn;
+ Flags.setSRet();
if (Args[i].isByVal) {
- Flags |= ISD::ParamFlags::ByVal;
+ Flags.setByVal();
const PointerType *Ty = cast<PointerType>(Args[i].Ty);
const Type *ElementTy = Ty->getElementType();
- unsigned FrameAlign = Log2_32(getByValTypeAlignment(ElementTy));
+ unsigned FrameAlign = getByValTypeAlignment(ElementTy);
unsigned FrameSize = getTargetData()->getABITypeSize(ElementTy);
// For ByVal, alignment should come from FE. BE will guess if this
// info is not there but there are cases it cannot get right.
if (Args[i].Alignment)
- FrameAlign = Log2_32(Args[i].Alignment);
- Flags |= ((ISD::ParamFlags::ParamFlagsTy)FrameAlign
- << ISD::ParamFlags::ByValAlignOffs);
- Flags |= ((ISD::ParamFlags::ParamFlagsTy)FrameSize
- << ISD::ParamFlags::ByValSizeOffs);
+ FrameAlign = Args[i].Alignment;
+ Flags.setByValAlign(FrameAlign);
+ Flags.setByValSize(FrameSize);
}
if (Args[i].isNest)
- Flags |= ISD::ParamFlags::Nest;
- Flags |= ((ISD::ParamFlags::ParamFlagsTy)OriginalAlignment)
- << ISD::ParamFlags::OrigAlignmentOffs;
+ Flags.setNest();
+ Flags.setOrigAlign(OriginalAlignment);
MVT::ValueType PartVT = getRegisterType(VT);
unsigned NumParts = getNumRegisters(VT);
@@ -4229,13 +4220,12 @@ TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy,
for (unsigned i = 0; i != NumParts; ++i) {
// if it isn't first piece, alignment must be 1
- ISD::ParamFlags::ParamFlagsTy MyFlags = Flags;
+ ISD::ArgFlagsTy MyFlags = Flags;
if (i != 0)
- MyFlags = (MyFlags & (~ISD::ParamFlags::OrigAlignment)) |
- (ISD::ParamFlags::One << ISD::ParamFlags::OrigAlignmentOffs);
+ MyFlags.setOrigAlign(1);
Ops.push_back(Parts[i]);
- Ops.push_back(DAG.getConstant(MyFlags, MVT::i64));
+ Ops.push_back(DAG.getArgFlags(MyFlags));
}
}
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp
index b316d417a9..ad58aa0616 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp
@@ -151,6 +151,8 @@ std::string DOTGraphTraits<SelectionDAG*>::getNodeLabel(const SDNode *Node,
Op += "<" + M->MO.getValue()->getName() + ":" + itostr(M->MO.getOffset()) + ">";
else
Op += "<null:" + itostr(M->MO.getOffset()) + ">";
+ } else if (const ARG_FLAGSSDNode *N = dyn_cast<ARG_FLAGSSDNode>(Node)) {
+ Op = Op + " AF=" + N->getArgFlags().getArgFlagsString();
} 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)) {