Add some convenience methods for querying attributes, and
authorDuncan Sands <baldrick@free.fr>
Wed, 28 Nov 2007 17:07:01 +0000 (17:07 +0000)
committerDuncan Sands <baldrick@free.fr>
Wed, 28 Nov 2007 17:07:01 +0000 (17:07 +0000)
use them.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@44403 91177308-0d34-0410-b5e6-96231b3b80d8

15 files changed:
include/llvm/Function.h
include/llvm/Instructions.h
include/llvm/Support/CallSite.h
lib/Analysis/BasicAliasAnalysis.cpp
lib/AsmParser/llvmAsmParser.cpp.cvs
lib/AsmParser/llvmAsmParser.y.cvs
lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
lib/ExecutionEngine/Interpreter/Execution.cpp
lib/Target/MSIL/MSILWriter.cpp
lib/Transforms/Scalar/SimplifyCFG.cpp
lib/VMCore/Function.cpp
lib/VMCore/Instructions.cpp
test/Transforms/SimplifyCFG/2007-11-22-InvokeNoUnwind.ll
tools/llvm-upgrade/UpgradeParser.cpp.cvs
tools/llvm-upgrade/UpgradeParser.y.cvs

index 897e53b0a2d250d335ffc743f8c76284ace4ffb2..627b47f9d9b2289f77ea7f1e653c6873dacc3abb 100644 (file)
@@ -21,6 +21,7 @@
 #include "llvm/GlobalValue.h"
 #include "llvm/BasicBlock.h"
 #include "llvm/Argument.h"
+#include "llvm/ParameterAttributes.h"
 #include "llvm/Support/Annotation.h"
 
 namespace llvm {
@@ -152,8 +153,15 @@ public:
   /// @brief Set the parameter attributes.
   void setParamAttrs(const ParamAttrsList *attrs);
 
+  /// @brief Determine whether the function has the given attribute.
+  bool paramHasAttr(uint16_t i, ParameterAttributes attr) const {
+    return ParamAttrs && ParamAttrs->paramHasAttr(i, attr);
+  }
+
   /// @brief Determine if the function returns a structure.
-  bool isStructReturn() const;
+  bool isStructReturn() const {
+    return paramHasAttr(1, ParamAttr::StructRet);
+  }
 
   /// deleteBody - This method deletes the body of the function, and converts
   /// the linkage to external.
index 96ca43d6cad68232aed639b88264fe2e789de512..34b22c7802774f950adcf93b6897424a3bda41f4 100644 (file)
@@ -20,6 +20,7 @@
 
 #include "llvm/InstrTypes.h"
 #include "llvm/DerivedTypes.h"
+#include "llvm/ParameterAttributes.h"
 
 namespace llvm {
 
@@ -923,8 +924,14 @@ public:
   /// @brief Set the parameter attributes.
   void setParamAttrs(const ParamAttrsList *attrs);
 
+  /// @brief Determine whether the call or the callee has the given attribute.
+  bool paramHasAttr(uint16_t i, ParameterAttributes attr) const;
+
   /// @brief Determine if the call returns a structure.
-  bool isStructReturn() const;
+  bool isStructReturn() const {
+    // Be friendly and also check the callee.
+    return paramHasAttr(1, ParamAttr::StructRet);
+  }
 
   /// getCalledFunction - Return the function being called by this instruction
   /// if it is a direct call.  If it is a call through a function pointer,
@@ -1701,8 +1708,14 @@ public:
   /// @brief Set the parameter attributes.
   void setParamAttrs(const ParamAttrsList *attrs);
 
+  /// @brief Determine whether the call or the callee has the given attribute.
+  bool paramHasAttr(uint16_t i, ParameterAttributes attr) const;
+
   /// @brief Determine if the call returns a structure.
-  bool isStructReturn() const;
+  bool isStructReturn() const {
+    // Be friendly and also check the callee.
+    return paramHasAttr(1, ParamAttr::StructRet);
+  }
 
   /// getCalledFunction - Return the function called, or null if this is an
   /// indirect function invocation.
index d03d209d5fb2b3577ac89e6cbbb5eb1dcf1d04e4..b613dffe97a26dcd89a590638c5f9a981435e755 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "llvm/Instruction.h"
 #include "llvm/BasicBlock.h"
+#include "llvm/ParameterAttributes.h"
 
 namespace llvm {
 
@@ -63,6 +64,9 @@ public:
   const ParamAttrsList *getParamAttrs() const;
   void setParamAttrs(const ParamAttrsList *PAL);
 
+  /// paramHasAttr - whether the call or the callee has the given attribute.
+  bool paramHasAttr(uint16_t i, ParameterAttributes attr) const;
+
   /// getType - Return the type of the instruction that generated this call site
   ///
   const Type *getType() const { return I->getType(); }
index 82dee547a9f97d51f08d4953a9d77005243dc331..575e9218eaa1a3cadde53be0efda6d238be44dbe 100644 (file)
@@ -839,10 +839,9 @@ BasicAliasAnalysis::getModRefBehavior(Function *F, CallSite CS,
     return UnknownModRefBehavior;
   }
 
-  const ParamAttrsList *Attrs = F->getParamAttrs();
-  if (Attrs && Attrs->paramHasAttr(0, ParamAttr::ReadNone))
+  if (F->paramHasAttr(0, ParamAttr::ReadNone))
     return DoesNotAccessMemory;
-  if (Attrs && Attrs->paramHasAttr(0, ParamAttr::ReadOnly))
+  if (F->paramHasAttr(0, ParamAttr::ReadOnly))
     return OnlyReadsMemory;
 
   return UnknownModRefBehavior;
index 5907eec578460bdb50eddb1c1bef09d0b0d9aefb..c5b414c73807151bc8c1fa467c86e4dd924cc734 100644 (file)
@@ -5161,7 +5161,7 @@ yyreduce:
   bool isVarArg = ParamTypeList.size() && ParamTypeList.back() == Type::VoidTy;
   if (isVarArg) ParamTypeList.pop_back();
 
-  ParamAttrsList *PAL = 0;
+  const ParamAttrsList *PAL = 0;
   if (!Attrs.empty())
     PAL = ParamAttrsList::get(Attrs);
 
@@ -5664,7 +5664,7 @@ yyreduce:
         GEN_ERROR("Invalid number of parameters detected");
     }
 
-    ParamAttrsList *PAL = 0;
+    const ParamAttrsList *PAL = 0;
     if (!Attrs.empty())
       PAL = ParamAttrsList::get(Attrs);
 
@@ -6094,7 +6094,7 @@ yyreduce:
     }
 
     // Finish off the ParamAttrs and check them
-    ParamAttrsList *PAL = 0;
+    const ParamAttrsList *PAL = 0;
     if (!Attrs.empty())
       PAL = ParamAttrsList::get(Attrs);
 
index 683b95b8fbaf553236104cf67af3833aa1652d08..31fd6190827d9530ee23ae3b27e0799c16225f88 100644 (file)
@@ -2243,7 +2243,7 @@ FunctionHeaderH : OptCallingConv ResultTypes GlobalName '(' ArgList ')'
   bool isVarArg = ParamTypeList.size() && ParamTypeList.back() == Type::VoidTy;
   if (isVarArg) ParamTypeList.pop_back();
 
-  ParamAttrsList *PAL = 0;
+  const ParamAttrsList *PAL = 0;
   if (!Attrs.empty())
     PAL = ParamAttrsList::get(Attrs);
 
@@ -2645,7 +2645,7 @@ BBTerminatorInst : RET ResolvedVal {              // Return with a result...
         GEN_ERROR("Invalid number of parameters detected");
     }
 
-    ParamAttrsList *PAL = 0;
+    const ParamAttrsList *PAL = 0;
     if (!Attrs.empty())
       PAL = ParamAttrsList::get(Attrs);
 
@@ -2977,7 +2977,7 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
     }
 
     // Finish off the ParamAttrs and check them
-    ParamAttrsList *PAL = 0;
+    const ParamAttrsList *PAL = 0;
     if (!Attrs.empty())
       PAL = ParamAttrsList::get(Attrs);
 
index 3ba886f05dac955e30f013fefbcbe6bae7d4c1bd..a350ea95f7a95d303cf26cd975c4099bcfa0a27c 100644 (file)
@@ -934,11 +934,11 @@ void SelectionDAGLowering::visitRet(ReturnInst &I) {
         TmpVT = TLI.getTypeToTransformTo(MVT::i32);
       else
         TmpVT = MVT::i32;
-      const ParamAttrsList *PAL = I.getParent()->getParent()->getParamAttrs();
+      const Function *F = I.getParent()->getParent();
       ISD::NodeType ExtendKind = ISD::ANY_EXTEND;
-      if (PAL && PAL->paramHasAttr(0, ParamAttr::SExt))
+      if (F->paramHasAttr(0, ParamAttr::SExt))
         ExtendKind = ISD::SIGN_EXTEND;
-      if (PAL && PAL->paramHasAttr(0, ParamAttr::ZExt))
+      if (F->paramHasAttr(0, ParamAttr::ZExt))
         ExtendKind = ISD::ZERO_EXTEND;
       RetOp = DAG.getNode(ExtendKind, TmpVT, RetOp);
       NewValues.push_back(RetOp);
@@ -3892,7 +3892,6 @@ void SelectionDAGLowering::visitVACopy(CallInst &I) {
 /// integrated into SDISel.
 std::vector<SDOperand> 
 TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
-  const ParamAttrsList *Attrs = F.getParamAttrs();
   // Add CC# and isVararg as operands to the FORMAL_ARGUMENTS node.
   std::vector<SDOperand> Ops;
   Ops.push_back(DAG.getRoot());
@@ -3911,15 +3910,15 @@ TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
 
     // FIXME: Distinguish between a formal with no [sz]ext attribute from one
     // that is zero extended!
-    if (Attrs && Attrs->paramHasAttr(j, ParamAttr::ZExt))
+    if (F.paramHasAttr(j, ParamAttr::ZExt))
       Flags &= ~(ISD::ParamFlags::SExt);
-    if (Attrs && Attrs->paramHasAttr(j, ParamAttr::SExt))
+    if (F.paramHasAttr(j, ParamAttr::SExt))
       Flags |= ISD::ParamFlags::SExt;
-    if (Attrs && Attrs->paramHasAttr(j, ParamAttr::InReg))
+    if (F.paramHasAttr(j, ParamAttr::InReg))
       Flags |= ISD::ParamFlags::InReg;
-    if (Attrs && Attrs->paramHasAttr(j, ParamAttr::StructRet))
+    if (F.paramHasAttr(j, ParamAttr::StructRet))
       Flags |= ISD::ParamFlags::StructReturn;
-    if (Attrs && Attrs->paramHasAttr(j, ParamAttr::ByVal)) {
+    if (F.paramHasAttr(j, ParamAttr::ByVal)) {
       Flags |= ISD::ParamFlags::ByVal;
       const PointerType *Ty = cast<PointerType>(I->getType());
       const StructType *STy = cast<StructType>(Ty->getElementType());
@@ -3929,7 +3928,7 @@ TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
       Flags |= (StructAlign << ISD::ParamFlags::ByValAlignOffs);
       Flags |= (StructSize  << ISD::ParamFlags::ByValSizeOffs);
     }
-    if (Attrs && Attrs->paramHasAttr(j, ParamAttr::Nest))
+    if (F.paramHasAttr(j, ParamAttr::Nest))
       Flags |= ISD::ParamFlags::Nest;
     Flags |= (OriginalAlignment << ISD::ParamFlags::OrigAlignmentOffs);
     
@@ -3986,10 +3985,10 @@ TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
     case Promote: {
       SDOperand Op(Result, i++);
       if (MVT::isInteger(VT)) {
-        if (Attrs && Attrs->paramHasAttr(Idx, ParamAttr::SExt))
+        if (F.paramHasAttr(Idx, ParamAttr::SExt))
           Op = DAG.getNode(ISD::AssertSext, Op.getValueType(), Op,
                            DAG.getValueType(VT));
-        else if (Attrs && Attrs->paramHasAttr(Idx, ParamAttr::ZExt))
+        else if (F.paramHasAttr(Idx, ParamAttr::ZExt))
           Op = DAG.getNode(ISD::AssertZext, Op.getValueType(), Op,
                            DAG.getValueType(VT));
         Op = DAG.getNode(ISD::TRUNCATE, VT, Op);
index 6ab123125f27bbc59af11869e14dc298a3eb053c..687814b9cea940539cf7e30100b0f556b817c3c1 100644 (file)
@@ -896,18 +896,15 @@ void Interpreter::visitCallSite(CallSite CS) {
          e = SF.Caller.arg_end(); i != e; ++i, ++pNum) {
     Value *V = *i;
     ArgVals.push_back(getOperandValue(V, SF));
-    if (F) {
-     // Promote all integral types whose size is < sizeof(i32) into i32.  
-     // We do this by zero or sign extending the value as appropriate 
-     // according to the parameter attributes
-      const Type *Ty = V->getType();
-      if (Ty->isInteger() && (ArgVals.back().IntVal.getBitWidth() < 32))
-        if (const ParamAttrsList *PA = F->getParamAttrs())
-          if (PA->paramHasAttr(pNum, ParamAttr::ZExt))
-            ArgVals.back().IntVal = ArgVals.back().IntVal.zext(32);
-          else if (PA->paramHasAttr(pNum, ParamAttr::SExt))
-            ArgVals.back().IntVal = ArgVals.back().IntVal.sext(32);
-     }
+    // Promote all integral types whose size is < sizeof(i32) into i32.
+    // We do this by zero or sign extending the value as appropriate
+    // according to the parameter attributes
+    const Type *Ty = V->getType();
+    if (Ty->isInteger() && (ArgVals.back().IntVal.getBitWidth() < 32))
+      if (CS.paramHasAttr(pNum, ParamAttr::ZExt))
+        ArgVals.back().IntVal = ArgVals.back().IntVal.zext(32);
+      else if (CS.paramHasAttr(pNum, ParamAttr::SExt))
+        ArgVals.back().IntVal = ArgVals.back().IntVal.sext(32);
   }
 
   // To handle indirect calls, we must get the pointer value from the argument
index 2fe4f3b15dca52fc0aa97422e93f816720c9fe4a..dafdbe7b2e9feae810e2c41cf406cf0d29d6a755 100644 (file)
@@ -1387,8 +1387,7 @@ void MSILWriter::printStaticInitializerList() {
 
 
 void MSILWriter::printFunction(const Function& F) {
-  const ParamAttrsList *Attrs = F.getParamAttrs();
-  bool isSigned = Attrs && Attrs->paramHasAttr(0, ParamAttr::SExt);
+  bool isSigned = F.paramHasAttr(0, ParamAttr::SExt);
   Out << "\n.method static ";
   Out << (F.hasInternalLinkage() ? "private " : "public ");
   if (F.isVarArg()) Out << "vararg ";
@@ -1399,7 +1398,7 @@ void MSILWriter::printFunction(const Function& F) {
   unsigned ArgIdx = 1;
   for (Function::const_arg_iterator I = F.arg_begin(), E = F.arg_end(); I!=E;
        ++I, ++ArgIdx) {
-    isSigned = Attrs && Attrs->paramHasAttr(ArgIdx, ParamAttr::SExt);
+    isSigned = F.paramHasAttr(ArgIdx, ParamAttr::SExt);
     if (I!=F.arg_begin()) Out << ", ";
     Out << getTypeName(I->getType(),isSigned) << getValueName(I);
   }
index 22d81c881ec4193a9ff93a7d53b36047b0df11d9..ed51746b3ce32a5e034dd589d1ba8ebf128ff895 100644 (file)
@@ -90,35 +90,6 @@ static void ChangeToCall(InvokeInst *II) {
   BB->getInstList().erase(II);
 }
 
-/// IsNoReturn - Return true if the specified call is to a no-return function.
-static bool IsNoReturn(const CallInst *CI) {
-  if (const ParamAttrsList *Attrs = CI->getParamAttrs())
-    if (Attrs->paramHasAttr(0, ParamAttr::NoReturn))
-      return true;
-  
-  if (const Function *Callee = CI->getCalledFunction())
-    if (const ParamAttrsList *Attrs = Callee->getParamAttrs())
-      if (Attrs->paramHasAttr(0, ParamAttr::NoReturn))
-        return true;
-
-  return false;
-}
-
-/// IsNoUnwind - Return true if the specified invoke is to a no-unwind function.
-static bool IsNoUnwind(const InvokeInst *II) {
-  if (const ParamAttrsList *Attrs = II->getParamAttrs())
-    if (Attrs->paramHasAttr(0, ParamAttr::NoUnwind))
-      return true;
-  
-  if (const Function *Callee = II->getCalledFunction())
-    if (const ParamAttrsList *Attrs = Callee->getParamAttrs())
-      if (Attrs->paramHasAttr(0, ParamAttr::NoUnwind))
-        return true;
-
-  return false;
-}
-
-
 static bool MarkAliveBlocks(BasicBlock *BB,
                             SmallPtrSet<BasicBlock*, 128> &Reachable) {
   
@@ -137,7 +108,7 @@ static bool MarkAliveBlocks(BasicBlock *BB,
     // canonicalizes unreachable insts into stores to null or undef.
     for (BasicBlock::iterator BBI = BB->begin(), E = BB->end(); BBI != E;++BBI){
       if (CallInst *CI = dyn_cast<CallInst>(BBI)) {
-        if (IsNoReturn(CI)) {
+        if (CI->paramHasAttr(0, ParamAttr::NoReturn)) {
           // If we found a call to a no-return function, insert an unreachable
           // instruction after it.  Make sure there isn't *already* one there
           // though.
@@ -161,7 +132,7 @@ static bool MarkAliveBlocks(BasicBlock *BB,
 
     // Turn invokes that call 'nounwind' functions into ordinary calls.
     if (InvokeInst *II = dyn_cast<InvokeInst>(BB->getTerminator()))
-      if (IsNoUnwind(II)) {
+      if (II->paramHasAttr(0, ParamAttr::NoUnwind)) {
         ChangeToCall(II);
         Changed = true;
       }
index 023cb556f44e720eb43f24fd555d9809482b3c82..92853e30f9b78dd17c21f466a2dd03b8f331de66 100644 (file)
@@ -13,7 +13,6 @@
 
 #include "llvm/Module.h"
 #include "llvm/DerivedTypes.h"
-#include "llvm/ParameterAttributes.h"
 #include "llvm/IntrinsicInst.h"
 #include "llvm/CodeGen/ValueTypes.h"
 #include "llvm/Support/LeakDetector.h"
@@ -287,12 +286,6 @@ void Function::setParamAttrs(const ParamAttrsList *attrs) {
   ParamAttrs = attrs; 
 }
 
-bool Function::isStructReturn() const {
-  if (ParamAttrs)
-    return ParamAttrs->paramHasAttr(1, ParamAttr::StructRet);
-  return false;
-}
-
 const FunctionType *Function::getFunctionType() const {
   return cast<FunctionType>(getType()->getElementType());
 }
index 7226f66e2094052c0e3c90c335d84951cd837e66..8e484910d2d7597e588531f150addcd427f35084 100644 (file)
@@ -47,6 +47,12 @@ void CallSite::setParamAttrs(const ParamAttrsList *PAL) {
   else
     cast<InvokeInst>(I)->setParamAttrs(PAL);
 }
+bool CallSite::paramHasAttr(uint16_t i, ParameterAttributes attr) const {
+  if (CallInst *CI = dyn_cast<CallInst>(I))
+    return CI->paramHasAttr(i, attr);
+  else
+    return cast<InvokeInst>(I)->paramHasAttr(i, attr);
+}
 
 
 
@@ -376,12 +382,14 @@ void CallInst::setParamAttrs(const ParamAttrsList *newAttrs) {
   ParamAttrs = newAttrs; 
 }
 
-bool CallInst::isStructReturn() const {
-  if (ParamAttrs)
-    return ParamAttrs->paramHasAttr(1, ParamAttr::StructRet);
-  return false;
+bool CallInst::paramHasAttr(uint16_t i, ParameterAttributes attr) const {
+  if (ParamAttrs && ParamAttrs->paramHasAttr(i, attr))
+    return true;
+  const Function *F = getCalledFunction();
+  return F && F->getParamAttrs() && F->getParamAttrs()->paramHasAttr(i, attr);
 }
 
+
 //===----------------------------------------------------------------------===//
 //                        InvokeInst Implementation
 //===----------------------------------------------------------------------===//
@@ -451,12 +459,14 @@ void InvokeInst::setParamAttrs(const ParamAttrsList *newAttrs) {
   ParamAttrs = newAttrs; 
 }
 
-bool InvokeInst::isStructReturn() const {
-  if (ParamAttrs)
-    return ParamAttrs->paramHasAttr(1, ParamAttr::StructRet);
-  return false;
+bool InvokeInst::paramHasAttr(uint16_t i, ParameterAttributes attr) const {
+  if (ParamAttrs && ParamAttrs->paramHasAttr(i, attr))
+    return true;
+  const Function *F = getCalledFunction();
+  return F && F->getParamAttrs() && F->getParamAttrs()->paramHasAttr(i, attr);
 }
 
+
 //===----------------------------------------------------------------------===//
 //                        ReturnInst Implementation
 //===----------------------------------------------------------------------===//
index 8e8ef43932b2839ab78e3249fca2bfb2b8857b17..449047b0d32f6e7a9cd8df3f5dccb99845d5cba1 100644 (file)
@@ -3,7 +3,7 @@
 declare i32 @func(i8*) nounwind
 
 define i32 @test() {
-       invoke i32 @func( i8* null ) nounwind
+       invoke i32 @func( i8* null )
                        to label %Cont unwind label %Other              ; <i32>:1 [#uses=0]
 
 Cont:          ; preds = %0
index 8f8327ec40bdd4f7682ece002b13c58db921aa89..dce1836b867632196a5ee1492f8bf44c6b9d25c4 100644 (file)
@@ -4510,7 +4510,7 @@ yyreduce:
     bool isVarArg = Params.size() && Params.back() == Type::VoidTy;
     if (isVarArg) Params.pop_back();
 
-    ParamAttrsList *PAL = 0;
+    const ParamAttrsList *PAL = 0;
     if (lastCallingConv == OldCallingConv::CSRet) {
       ParamAttrsVector Attrs;
       ParamAttrsWithIndex PAWI;
index b9a26cb95726ec043c2df2e79463df41bf2cbc41..7a6e3efc7b0b36056c379606343774c95c02a5b8 100644 (file)
@@ -2055,7 +2055,7 @@ UpRTypes
     bool isVarArg = Params.size() && Params.back() == Type::VoidTy;
     if (isVarArg) Params.pop_back();
 
-    ParamAttrsList *PAL = 0;
+    const ParamAttrsList *PAL = 0;
     if (lastCallingConv == OldCallingConv::CSRet) {
       ParamAttrsVector Attrs;
       ParamAttrsWithIndex PAWI;