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
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits