Skip to content

[CIR][ABI] Add unsigned int CC lowering for x86_64 #701

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 51 additions & 6 deletions clang/include/clang/CIR/ABIArgInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

#include "mlir/IR/Types.h"
#include "clang/AST/Type.h"
#include "clang/CIR/Dialect/IR/CIRTypes.h"
#include <cstdint>

namespace cir {
Expand Down Expand Up @@ -99,6 +100,7 @@ class ABIArgInfo {
unsigned AllocaFieldIndex; // isInAlloca()
};
Kind TheKind;
bool InReg : 1; // isDirect() || isExtend() || isIndirect()
bool CanBeFlattened : 1; // isDirect()
bool SignExt : 1; // isExtend()

Expand All @@ -115,7 +117,7 @@ class ABIArgInfo {
public:
ABIArgInfo(Kind K = Direct)
: TypeData(nullptr), PaddingType(nullptr), DirectAttr{0, 0}, TheKind(K),
CanBeFlattened(false) {}
InReg(false), CanBeFlattened(false), SignExt(false) {}

static ABIArgInfo getDirect(mlir::Type T = nullptr, unsigned Offset = 0,
mlir::Type Padding = nullptr,
Expand All @@ -139,6 +141,16 @@ class ABIArgInfo {
AI.setSignExt(true);
return AI;
}
static ABIArgInfo getSignExtend(mlir::Type Ty, mlir::Type T = nullptr) {
// NOTE(cir): Enumerations are IntTypes in CIR.
auto AI = ABIArgInfo(Extend);
AI.setCoerceToType(T);
AI.setPaddingType(nullptr);
AI.setDirectOffset(0);
AI.setDirectAlign(0);
AI.setSignExt(true);
return AI;
}

static ABIArgInfo getZeroExtend(clang::QualType Ty, mlir::Type T = nullptr) {
assert(Ty->isIntegralOrEnumerationType() && "Unexpected QualType");
Expand All @@ -150,6 +162,18 @@ class ABIArgInfo {
AI.setSignExt(false);
return AI;
}
static ABIArgInfo getZeroExtend(mlir::Type Ty, mlir::Type T = nullptr) {
// NOTE(cir): Enumerations are IntTypes in CIR.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IntTypes or BoolTy?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IntTypes

assert(mlir::isa<mlir::cir::IntType>(Ty) ||
mlir::isa<mlir::cir::BoolType>(Ty));
auto AI = ABIArgInfo(Extend);
AI.setCoerceToType(T);
AI.setPaddingType(nullptr);
AI.setDirectOffset(0);
AI.setDirectAlign(0);
AI.setSignExt(false);
return AI;
}

// ABIArgInfo will record the argument as being extended based on the sign of
// it's type.
Expand All @@ -159,6 +183,14 @@ class ABIArgInfo {
return getSignExtend(Ty, T);
return getZeroExtend(Ty, T);
}
static ABIArgInfo getExtend(mlir::Type Ty, mlir::Type T = nullptr) {
// NOTE(cir): The original can apply this method on both integers and
// enumerations, but in CIR, these two types are one and the same.
if (mlir::isa<mlir::cir::IntType>(Ty) &&
mlir::cast<mlir::cir::IntType>(Ty).isSigned())
return getSignExtend(mlir::cast<mlir::cir::IntType>(Ty), T);
return getZeroExtend(Ty, T);
}

static ABIArgInfo getIgnore() { return ABIArgInfo(Ignore); }

Expand All @@ -171,6 +203,24 @@ class ABIArgInfo {
bool isExpand() const { return TheKind == Expand; }
bool isCoerceAndExpand() const { return TheKind == CoerceAndExpand; }

bool isSignExt() const {
assert(isExtend() && "Invalid kind!");
return SignExt;
}
void setSignExt(bool SExt) {
assert(isExtend() && "Invalid kind!");
SignExt = SExt;
}

bool getInReg() const {
assert((isDirect() || isExtend() || isIndirect()) && "Invalid kind!");
return InReg;
}
void setInReg(bool IR) {
assert((isDirect() || isExtend() || isIndirect()) && "Invalid kind!");
InReg = IR;
}

bool canHaveCoerceToType() const {
return isDirect() || isExtend() || isCoerceAndExpand();
}
Expand All @@ -191,11 +241,6 @@ class ABIArgInfo {
DirectAttr.Align = Align;
}

void setSignExt(bool SExt) {
assert(isExtend() && "Invalid kind!");
SignExt = SExt;
}

void setCanBeFlattened(bool Flatten) {
assert(isDirect() && "Invalid kind!");
CanBeFlattened = Flatten;
Expand Down
5 changes: 5 additions & 0 deletions clang/include/clang/CIR/Dialect/IR/CIRDialect.td
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ def CIR_Dialect : Dialect {
let useDefaultTypePrinterParser = 0;

let extraClassDeclaration = [{

// Names of CIR parameter attributes.
static StringRef getSExtAttrName() { return "cir.signext"; }
static StringRef getZExtAttrName() { return "cir.zeroext"; }

void registerAttributes();
void registerTypes();

Expand Down
18 changes: 18 additions & 0 deletions clang/include/clang/CIR/MissingFeatures.h
Original file line number Diff line number Diff line change
Expand Up @@ -201,18 +201,32 @@ struct MissingFeatures {
static bool funcDeclIsInlineBuiltinDeclaration() { return false; }
static bool funcDeclIsReplaceableGlobalAllocationFunction() { return false; }
static bool qualTypeIsReferenceType() { return false; }
static bool typeGetAsEnumType() { return false; }
static bool typeGetAsBuiltinType() { return false; }
static bool varDeclIsKNRPromoted() { return false; }

//-- Missing types

static bool fixedWidthIntegers() { return false; }
static bool vectorType() { return false; }

//-- Missing LLVM attributes

static bool noReturn() { return false; }
static bool csmeCall() { return false; }
static bool undef() { return false; }
static bool noFPClass() { return false; }

//-- Other missing features

// Empty values might be passed as arguments to serve as padding, ensuring
// alignment and compliance (e.g. MIPS). We do not yet support this.
static bool argumentPadding() { return false; }

// Clang has evaluation kinds which determines how code is emitted for certain
// group of type classes. We don't have a way to identify type classes.
static bool evaluationKind() { return false; }

// Calls with a static chain pointer argument may be optimized (p.e. freeing
// up argument registers), but we do not yet track such cases.
static bool chainCall() { return false; }
Expand Down Expand Up @@ -247,6 +261,10 @@ struct MissingFeatures {
// Despite carrying some information about variadics, we are currently
// ignoring this to focus only on the code necessary to lower non-variadics.
static bool variadicFunctions() { return false; }

// If a store op is guaranteed to execute before the retun value load op, we
// can optimize away the store and load ops. Seems like an early optimization.
static bool returnValueDominatingStoreOptmiization() { return false; }
};

} // namespace cir
Expand Down
12 changes: 12 additions & 0 deletions clang/include/clang/CIR/TypeEvaluationKind.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#ifndef CLANG_CIR_TYPEEVALUATIONKIND_H
#define CLANG_CIR_TYPEEVALUATIONKIND_H

namespace cir {

// FIXME: for now we are reusing this from lib/Clang/CIRGenFunction.h, which
// isn't available in the include dir. Same for getEvaluationKind below.
enum TypeEvaluationKind { TEK_Scalar, TEK_Complex, TEK_Aggregate };

} // namespace cir

#endif // CLANG_CIR_TYPEEVALUATIONKIND_H
1 change: 0 additions & 1 deletion clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,6 @@ static mlir::Value MakeAtomicCmpXchgValue(CIRGenFunction &cgf,

auto intType = builder.getSIntNTy(cgf.getContext().getTypeSize(typ));
auto cmpVal = cgf.buildScalarExpr(expr->getArg(1));
auto valueType = cmpVal.getType();
cmpVal = buildToInt(cgf, cmpVal, typ, intType);
auto newVal =
buildToInt(cgf, cgf.buildScalarExpr(expr->getArg(2)), typ, intType);
Expand Down
4 changes: 1 addition & 3 deletions clang/lib/CIR/CodeGen/CIRGenFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "clang/AST/Type.h"
#include "clang/Basic/ABI.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/CIR/TypeEvaluationKind.h"

#include "mlir/IR/TypeRange.h"
#include "mlir/IR/Value.h"
Expand All @@ -49,9 +50,6 @@ class AggExprEmitter;

namespace cir {

// FIXME: for now we are reusing this from lib/Clang/CIRGenFunction.h, which
// isn't available in the include dir. Same for getEvaluationKind below.
enum TypeEvaluationKind { TEK_Scalar, TEK_Complex, TEK_Aggregate };
struct CGCoroData;

class CIRGenFunction : public CIRGenTypeCache {
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/CIR/Dialect/Transforms/CallConvLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ LowerModule createLowerModule(FuncOp op, PatternRewriter &rewriter) {
// Create context.
assert(!::cir::MissingFeatures::langOpts());
clang::LangOptions langOpts;
auto context = CIRLowerContext(module.getContext(), langOpts);
auto context = CIRLowerContext(module, langOpts);
context.initBuiltinTypes(*targetInfo);

return LowerModule(context, module, dataLayoutStr, *targetInfo, rewriter);
Expand Down
12 changes: 12 additions & 0 deletions clang/lib/CIR/Dialect/Transforms/TargetLowering/ABIInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

#include "ABIInfo.h"
#include "CIRCXXABI.h"
#include "CIRLowerContext.h"
#include "LowerTypes.h"

namespace mlir {
Expand All @@ -23,5 +24,16 @@ ABIInfo::~ABIInfo() = default;

CIRCXXABI &ABIInfo::getCXXABI() const { return LT.getCXXABI(); }

CIRLowerContext &ABIInfo::getContext() const { return LT.getContext(); }

bool ABIInfo::isPromotableIntegerTypeForABI(Type Ty) const {
if (getContext().isPromotableIntegerType(Ty))
return true;

assert(!::cir::MissingFeatures::fixedWidthIntegers());

return false;
}

} // namespace cir
} // namespace mlir
7 changes: 7 additions & 0 deletions clang/lib/CIR/Dialect/Transforms/TargetLowering/ABIInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#define LLVM_CLANG_LIB_CIR_DIALECT_TRANSFORMS_TARGETLOWERING_ABIINFO_H

#include "CIRCXXABI.h"
#include "CIRLowerContext.h"
#include "LowerFunctionInfo.h"
#include "llvm/IR/CallingConv.h"

Expand All @@ -37,7 +38,13 @@ class ABIInfo {

CIRCXXABI &getCXXABI() const;

CIRLowerContext &getContext() const;

virtual void computeInfo(LowerFunctionInfo &FI) const = 0;

// Implement the Type::IsPromotableIntegerType for ABI specific needs. The
// only difference is that this considers bit-precise integer types as well.
bool isPromotableIntegerTypeForABI(Type Ty) const;
};

} // namespace cir
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,13 @@ bool classifyReturnType(const CIRCXXABI &CXXABI, LowerFunctionInfo &FI,
return CXXABI.classifyReturnType(FI);
}

Type useFirstFieldIfTransparentUnion(Type Ty) {
if (auto RT = dyn_cast<StructType>(Ty)) {
if (RT.isUnion())
llvm_unreachable("NYI");
}
return Ty;
}

} // namespace cir
} // namespace mlir
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ namespace cir {
bool classifyReturnType(const CIRCXXABI &CXXABI, LowerFunctionInfo &FI,
const ABIInfo &Info);

/// Pass transparent unions as if they were the type of the first element. Sema
/// should ensure that all elements of the union have the same "machine type".
Type useFirstFieldIfTransparentUnion(Type Ty);

} // namespace cir
} // namespace mlir

Expand Down
Loading
Loading