rogfer01 updated this revision to Diff 153070.
rogfer01 added a comment.

ChangeLog:

- Use a  `ConstantDataArray` instead of a struct of types.
- Use `LLVM_IS_TRIVIALLY_COPYABLE`


https://reviews.llvm.org/D48589

Files:
  include/clang/CodeGen/CGFunctionInfo.h
  lib/CodeGen/CGCall.cpp

Index: lib/CodeGen/CGCall.cpp
===================================================================
--- lib/CodeGen/CGCall.cpp
+++ lib/CodeGen/CGCall.cpp
@@ -1951,7 +1951,6 @@
 
   case ABIArgInfo::CoerceAndExpand:
     break;
-
   case ABIArgInfo::Expand:
     llvm_unreachable("Invalid ABI kind for return argument");
   }
@@ -1987,6 +1986,8 @@
         llvm::AttributeSet::get(getLLVMContext(), Attrs);
   }
 
+  SmallVector<llvm::AttrBuilder, 4> CoerceAndExpandAttrs(IRFunctionArgs.totalIRArgs());
+  bool CoerceAndExpandHasAttributes = false;
   unsigned ArgNo = 0;
   for (CGFunctionInfo::const_arg_iterator I = FI.arg_begin(),
                                           E = FI.arg_end();
@@ -2055,9 +2056,39 @@
     }
     case ABIArgInfo::Ignore:
     case ABIArgInfo::Expand:
-    case ABIArgInfo::CoerceAndExpand:
       break;
+    case ABIArgInfo::CoerceAndExpand:
+      if (AI.getExtendSeq()) {
+        // Handle extends in expanded items
+        unsigned FirstIRArg, NumIRArgs;
+        std::tie(FirstIRArg, NumIRArgs) = IRFunctionArgs.getIRArgs(ArgNo);
+        llvm::StructType *CoercionType = AI.getCoerceAndExpandType();
+        for (unsigned I = 0, Ext = 0; I < NumIRArgs; I++) {
+          llvm::Type *EltType = CoercionType->getElementType(I);
+          if (ABIArgInfo::isPaddingForCoerceAndExpand(EltType))
+            continue;
 
+          uint64_t ExtendKind = AI.getExtendSeq()->getElementAsInteger(Ext++);
+          switch (ABIArgInfo::getExtendKind(ExtendKind)) {
+          case ABIArgInfo::ExtendKind::None:
+            break;
+          case ABIArgInfo::ExtendKind::SignExt: {
+            CoerceAndExpandHasAttributes = true;
+            CoerceAndExpandAttrs[FirstIRArg + I].addAttribute(
+                llvm::Attribute::SExt);
+            break;
+          }
+          case ABIArgInfo::ExtendKind::ZeroExt: {
+            CoerceAndExpandHasAttributes = true;
+            CoerceAndExpandAttrs[FirstIRArg + I].addAttribute(
+                llvm::Attribute::ZExt);
+            break;
+          }
+          }
+        }
+      }
+
+      break;
     case ABIArgInfo::InAlloca:
       // inalloca disables readnone and readonly.
       FuncAttrs.removeAttribute(llvm::Attribute::ReadOnly)
@@ -2112,12 +2143,16 @@
     if (FI.getExtParameterInfo(ArgNo).isNoEscape())
       Attrs.addAttribute(llvm::Attribute::NoCapture);
 
-    if (Attrs.hasAttributes()) {
+    if (Attrs.hasAttributes() || CoerceAndExpandHasAttributes) {
       unsigned FirstIRArg, NumIRArgs;
       std::tie(FirstIRArg, NumIRArgs) = IRFunctionArgs.getIRArgs(ArgNo);
       for (unsigned i = 0; i < NumIRArgs; i++)
+      {
+        llvm::AttrBuilder CoerceAndExpandMergedAttrs(Attrs);
+        CoerceAndExpandMergedAttrs.merge(CoerceAndExpandAttrs[FirstIRArg + i]);
         ArgAttrs[FirstIRArg + i] =
-            llvm::AttributeSet::get(getLLVMContext(), Attrs);
+            llvm::AttributeSet::get(getLLVMContext(), CoerceAndExpandMergedAttrs);
+      }
     }
   }
   assert(ArgNo == FI.arg_size());
Index: include/clang/CodeGen/CGFunctionInfo.h
===================================================================
--- include/clang/CodeGen/CGFunctionInfo.h
+++ include/clang/CodeGen/CGFunctionInfo.h
@@ -22,8 +22,10 @@
 #include "clang/AST/Decl.h"
 #include "clang/AST/Type.h"
 #include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Constants.h"
 #include "llvm/ADT/FoldingSet.h"
 #include "llvm/Support/TrailingObjects.h"
+#include "llvm/Support/type_traits.h"
 #include <cassert>
 
 namespace clang {
@@ -76,16 +78,20 @@
     KindLast = InAlloca
   };
 
+  enum class ExtendKind : unsigned { None = 1, SignExt = 2, ZeroExt = 3 };
+
 private:
+
   llvm::Type *TypeData; // canHaveCoerceToType()
   union {
     llvm::Type *PaddingType; // canHavePaddingType()
     llvm::Type *UnpaddedCoerceAndExpandType; // isCoerceAndExpand()
   };
   union {
-    unsigned DirectOffset;     // isDirect() || isExtend()
-    unsigned IndirectAlign;    // isIndirect()
-    unsigned AllocaFieldIndex; // isInAlloca()
+    llvm::ConstantDataArray *ExtendSeq; // isCoerceAndExpand()
+    unsigned DirectOffset;              // isDirect() || isExtend()
+    unsigned IndirectAlign;             // isIndirect()
+    unsigned AllocaFieldIndex;          // isInAlloca()
   };
   Kind TheKind;
   bool PaddingInReg : 1;
@@ -110,13 +116,16 @@
     UnpaddedCoerceAndExpandType = T;
   }
 
-  ABIArgInfo(Kind K)
-      : TheKind(K), PaddingInReg(false), InReg(false) {
+  void setExtendSet(llvm::ConstantDataArray *ES) {
+    assert(isCoerceAndExpand());
+    ExtendSeq = ES;
   }
 
+  ABIArgInfo(Kind K) : TheKind(K), PaddingInReg(false), InReg(false) {}
+
 public:
   ABIArgInfo()
-      : TypeData(nullptr), PaddingType(nullptr), DirectOffset(0),
+      : TypeData(nullptr), PaddingType(nullptr), ExtendSeq(nullptr),
         TheKind(Direct), PaddingInReg(false), InReg(false) {}
 
   static ABIArgInfo getDirect(llvm::Type *T = nullptr, unsigned Offset = 0,
@@ -210,8 +219,15 @@
   /// \param unpaddedCoerceToType The coerce-to type with padding elements
   ///   removed, canonicalized to a single element if it would otherwise
   ///   have exactly one element.
-  static ABIArgInfo getCoerceAndExpand(llvm::StructType *coerceToType,
-                                       llvm::Type *unpaddedCoerceToType) {
+  /// \param extendSet The extension to be applied to the expanded type. It is
+  //    represented by a constant data array of integers where each integer
+  //    is a value of ExtendKind. If null no extension is applied. If not null
+  //    it has as many elements as unpaddedCoerceToType. Only integral-types can
+  //    have an extension other than None.
+  static ABIArgInfo
+  getCoerceAndExpand(llvm::StructType *coerceToType,
+                     llvm::Type *unpaddedCoerceToType,
+                     llvm::ConstantDataArray *extendSet = nullptr) {
 #ifndef NDEBUG
     // Sanity checks on unpaddedCoerceToType.
 
@@ -238,11 +254,38 @@
     } else {
       assert(unpaddedIndex == 1);
     }
+
+    if (extendSet) {
+      // Assert that the size of the extend struct agrees with the unpadded
+      // struct and it only attempts to extend integral types.
+      if (unpaddedStruct) {
+        assert(extendSet->getNumElements() == unpaddedStruct->getNumElements());
+        unsigned Idx = 0;
+        for (auto EltType : unpaddedStruct->elements()) {
+          uint64_t ExtendType = extendSet->getElementAsInteger(Idx);
+          assert(ExtendType == static_cast<uint64_t>(ExtendKind::None) ||
+                 (ExtendType == static_cast<uint64_t>(ExtendKind::ZeroExt) ||
+                  ExtendType == static_cast<uint64_t>(ExtendKind::SignExt)) &&
+                     EltType->isIntegerTy() &&
+                     "Invalid extend applied to non-integral type");
+          Idx++;
+        }
+      } else {
+        assert(extendSet->getNumElements() == 1);
+        uint64_t ExtendType = extendSet->getElementAsInteger(0);
+        assert(ExtendType == static_cast<uint64_t>(ExtendKind::None) ||
+               (ExtendType == static_cast<uint64_t>(ExtendKind::ZeroExt) ||
+                ExtendType == static_cast<uint64_t>(ExtendKind::SignExt)) &&
+                   unpaddedCoerceToType->isIntegerTy() &&
+                   "Invalid extend applied to non-integral type");
+      }
+    }
 #endif
 
     auto AI = ABIArgInfo(CoerceAndExpand);
     AI.setCoerceToType(coerceToType);
     AI.setUnpaddedCoerceToType(unpaddedCoerceToType);
+    AI.setExtendSet(extendSet);
     return AI;
   }
 
@@ -255,6 +298,15 @@
     }
   }
 
+  static ExtendKind getExtendKind(uint64_t I) {
+    ExtendKind EK = static_cast<ExtendKind>(I);
+    if (EK == ExtendKind::None || EK == ExtendKind::SignExt ||
+        EK == ExtendKind::ZeroExt) {
+      return EK;
+    }
+    llvm_unreachable("Unexpected integer kind");
+  }
+
   Kind getKind() const { return TheKind; }
   bool isDirect() const { return TheKind == Direct; }
   bool isInAlloca() const { return TheKind == InAlloca; }
@@ -318,6 +370,11 @@
     return UnpaddedCoerceAndExpandType;
   }
 
+  llvm::ConstantDataArray *getExtendSeq() const {
+    assert(isCoerceAndExpand());
+    return ExtendSeq;
+  }
+
   ArrayRef<llvm::Type *>getCoerceAndExpandTypeSequence() const {
     assert(isCoerceAndExpand());
     if (auto structTy =
@@ -409,6 +466,13 @@
   void dump() const;
 };
 
+#if defined(LLVM_IS_TRIVIALLY_COPYABLE)
+static_assert(
+    LLVM_IS_TRIVIALLY_COPYABLE(ABIArgInfo),
+    "ABIArgInfo must be trivially copyable as it is embedded as trailing "
+    "data of CGFunctionInfo");
+#endif
+
 /// A class for recording the number of arguments that a function
 /// signature requires.
 class RequiredArgs {
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to