Introduce a new node for holding call argument
flags.  This is needed by the new legalize types
infrastructure which wants to expand the 64 bit
constants previously used to hold the flags on
32 bit machines.  There are two functional changes:
(1) in LowerArguments, if a parameter has the zext
attribute set then that is marked in the flags;
before it was being ignored; (2) PPC had some bogus
code for handling two word arguments when using the
ELF 32 ABI, which was hard to convert because of
the bogusness.  As suggested by the original author
(Nicolas Geoffray), I've disabled it for the moment.
Tested with "make check" and the Ada ACATS testsuite.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@48640 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/SelectionDAG/CallingConvLower.cpp b/lib/CodeGen/SelectionDAG/CallingConvLower.cpp
index 6b9b31b..667870d 100644
--- a/lib/CodeGen/SelectionDAG/CallingConvLower.cpp
+++ b/lib/CodeGen/SelectionDAG/CallingConvLower.cpp
@@ -35,11 +35,9 @@
 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 @@
   
   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 @@
   // 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 @@
   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::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 56ac375..d318cb4 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -808,6 +808,7 @@
   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 3cd7310..9331e8b 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -355,6 +355,9 @@
   // 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 @@
   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 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 @@
 
   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 @@
   }
 }
 
+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 @@
       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 1e249d0..d9d58fa 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -1064,7 +1064,7 @@
 
     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 @@
   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 @@
       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 @@
   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 @@
 
     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 b316d41..ad58aa0 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp
@@ -151,6 +151,8 @@
       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)) {