Skip to content
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
2 changes: 0 additions & 2 deletions clang/lib/CIR/CodeGen/ABIInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ class ABIInfo {
ABIInfo(CIRGenTypes &cgt) : cgt(cgt) {}

virtual ~ABIInfo();

virtual void computeInfo(CIRGenFunctionInfo &funcInfo) const = 0;
};

} // namespace clang::CIRGen
Expand Down
196 changes: 42 additions & 154 deletions clang/lib/CIR/CodeGen/CIRGenCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,86 +39,6 @@ CIRGenFunctionInfo::create(CanQualType resultType,
return fi;
}

namespace {

/// Encapsulates information about the way function arguments from
/// CIRGenFunctionInfo should be passed to actual CIR function.
class ClangToCIRArgMapping {
static constexpr unsigned invalidIndex = ~0U;
unsigned totalNumCIRArgs;

/// Arguments of CIR function corresponding to single Clang argument.
struct CIRArgs {
// Argument is expanded to CIR arguments at positions
// [FirstArgIndex, FirstArgIndex + NumberOfArgs).
unsigned firstArgIndex = 0;
unsigned numberOfArgs = 0;

CIRArgs() : firstArgIndex(invalidIndex), numberOfArgs(0) {}
};

SmallVector<CIRArgs, 8> argInfo;

public:
ClangToCIRArgMapping(const ASTContext &astContext,
const CIRGenFunctionInfo &funcInfo)
: totalNumCIRArgs(0), argInfo(funcInfo.arg_size()) {
unsigned cirArgNo = 0;

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

unsigned argNo = 0;
for (const CIRGenFunctionInfoArgInfo &i : funcInfo.arguments()) {
// Collect data about CIR arguments corresponding to Clang argument ArgNo.
CIRArgs &cirArgs = argInfo[argNo];

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

switch (i.info.getKind()) {
default:
assert(!cir::MissingFeatures::abiArgInfo());
// For now we just fall through. More argument kinds will be added later
// as the upstreaming proceeds.
[[fallthrough]];
case cir::ABIArgInfo::Direct:
// Postpone splitting structs into elements since this makes it way
// more complicated for analysis to obtain information on the original
// arguments.
//
// TODO(cir): a LLVM lowering prepare pass should break this down into
// the appropriated pieces.
assert(!cir::MissingFeatures::opCallABIExtendArg());
cirArgs.numberOfArgs = 1;
break;
}

if (cirArgs.numberOfArgs > 0) {
cirArgs.firstArgIndex = cirArgNo;
cirArgNo += cirArgs.numberOfArgs;
}

++argNo;
}

assert(argNo == argInfo.size());
assert(!cir::MissingFeatures::opCallInAlloca());

totalNumCIRArgs = cirArgNo;
}

unsigned totalCIRArgs() const { return totalNumCIRArgs; }

/// Returns index of first CIR argument corresponding to argNo, and their
/// quantity.
std::pair<unsigned, unsigned> getCIRArgs(unsigned argNo) const {
assert(argNo < argInfo.size());
return std::make_pair(argInfo[argNo].firstArgIndex,
argInfo[argNo].numberOfArgs);
}
};

} // namespace

CIRGenCallee CIRGenCallee::prepareConcreteCallee(CIRGenFunction &cgf) const {
assert(!cir::MissingFeatures::opCallVirtual());
return *this;
Expand Down Expand Up @@ -175,56 +95,38 @@ RValue CIRGenFunction::emitCall(const CIRGenFunctionInfo &funcInfo,
cir::CIRCallOpInterface *callOp,
mlir::Location loc) {
QualType retTy = funcInfo.getReturnType();
const cir::ABIArgInfo &retInfo = funcInfo.getReturnInfo();

ClangToCIRArgMapping cirFuncArgs(cgm.getASTContext(), funcInfo);
SmallVector<mlir::Value, 16> cirCallArgs(cirFuncArgs.totalCIRArgs());
SmallVector<mlir::Value, 16> cirCallArgs(args.size());

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

// Translate all of the arguments as necessary to match the CIR lowering.
assert(funcInfo.arg_size() == args.size() &&
"Mismatch between function signature & arguments.");
unsigned argNo = 0;
for (const auto &[arg, argInfo] : llvm::zip(args, funcInfo.arguments())) {
for (auto [argNo, arg, argInfo] :
llvm::enumerate(args, funcInfo.arguments())) {
// Insert a padding argument to ensure proper alignment.
assert(!cir::MissingFeatures::opCallPaddingArgs());

unsigned firstCIRArg;
unsigned numCIRArgs;
std::tie(firstCIRArg, numCIRArgs) = cirFuncArgs.getCIRArgs(argNo);

switch (argInfo.info.getKind()) {
case cir::ABIArgInfo::Direct: {
if (!mlir::isa<cir::RecordType>(argInfo.info.getCoerceToType()) &&
argInfo.info.getCoerceToType() == convertType(argInfo.type) &&
argInfo.info.getDirectOffset() == 0) {
assert(numCIRArgs == 1);
assert(!cir::MissingFeatures::opCallAggregateArgs());
mlir::Value v = arg.getKnownRValue().getScalarVal();

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

// We might have to widen integers, but we should never truncate.
assert(!cir::MissingFeatures::opCallWidenArg());

// If the argument doesn't match, perform a bitcast to coerce it. This
// can happen due to trivial type mismatches.
assert(!cir::MissingFeatures::opCallBitcastArg());

cirCallArgs[firstCIRArg] = v;
break;
}

mlir::Type argType = convertType(argInfo.type);
if (!mlir::isa<cir::RecordType>(argType)) {
mlir::Value v;
if (arg.isAggregate())
cgm.errorNYI(loc, "emitCall: aggregate call argument");
v = arg.getKnownRValue().getScalarVal();

// We might have to widen integers, but we should never truncate.
if (argType != v.getType() && mlir::isa<cir::IntType>(v.getType()))
cgm.errorNYI(loc, "emitCall: widening integer call argument");

// If the argument doesn't match, perform a bitcast to coerce it. This
// can happen due to trivial type mismatches.
// TODO(cir): When getFunctionType is added, assert that this isn't
// needed.
assert(!cir::MissingFeatures::opCallBitcastArg());
cirCallArgs[argNo] = v;
} else {
assert(!cir::MissingFeatures::opCallAggregateArgs());
cgm.errorNYI("emitCall: aggregate function call argument");
break;
}
default:
cgm.errorNYI("unsupported argument kind");
}

++argNo;
}

const CIRGenCallee &concreteCallee = callee.prepareConcreteCallee(*this);
Expand Down Expand Up @@ -256,45 +158,31 @@ RValue CIRGenFunction::emitCall(const CIRGenFunctionInfo &funcInfo,
assert(!cir::MissingFeatures::opCallMustTail());
assert(!cir::MissingFeatures::opCallReturn());

switch (retInfo.getKind()) {
case cir::ABIArgInfo::Direct: {
mlir::Type retCIRTy = convertType(retTy);
if (retInfo.getCoerceToType() == retCIRTy &&
retInfo.getDirectOffset() == 0) {
switch (getEvaluationKind(retTy)) {
case cir::TEK_Scalar: {
mlir::ResultRange results = theCall->getOpResults();
assert(results.size() == 1 && "unexpected number of returns");

// If the argument doesn't match, perform a bitcast to coerce it. This
// can happen due to trivial type mismatches.
if (results[0].getType() != retCIRTy)
cgm.errorNYI(loc, "bitcast on function return value");

mlir::Region *region = builder.getBlock()->getParent();
if (region != theCall->getParentRegion())
cgm.errorNYI(loc, "function calls with cleanup");

return RValue::get(results[0]);
}
case cir::TEK_Complex:
case cir::TEK_Aggregate:
cgm.errorNYI(loc,
"unsupported evaluation kind of function call result");
return getUndefRValue(retTy);
}
llvm_unreachable("Invalid evaluation kind");
}
cgm.errorNYI(loc, "unsupported function call form");
mlir::Type retCIRTy = convertType(retTy);
if (isa<cir::VoidType>(retCIRTy))
return getUndefRValue(retTy);
switch (getEvaluationKind(retTy)) {
case cir::TEK_Scalar: {
mlir::ResultRange results = theCall->getOpResults();
assert(results.size() == 1 && "unexpected number of returns");

// If the argument doesn't match, perform a bitcast to coerce it. This
// can happen due to trivial type mismatches.
if (results[0].getType() != retCIRTy)
cgm.errorNYI(loc, "bitcast on function return value");

mlir::Region *region = builder.getBlock()->getParent();
if (region != theCall->getParentRegion())
cgm.errorNYI(loc, "function calls with cleanup");

return RValue::get(results[0]);
}
case cir::ABIArgInfo::Ignore:
// If we are ignoring an argument that had a result, make sure to construct
// the appropriate return value for our caller.
case cir::TEK_Complex:
case cir::TEK_Aggregate:
cgm.errorNYI(loc, "unsupported evaluation kind of function call result");
return getUndefRValue(retTy);
}

llvm_unreachable("Invalid return info kind");
llvm_unreachable("Invalid evaluation kind");
}

void CIRGenFunction::emitCallArg(CallArgList &args, const clang::Expr *e,
Expand Down
2 changes: 2 additions & 0 deletions clang/lib/CIR/CodeGen/CIRGenCall.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ struct CallArg {
assert(!hasLV && !isUsed);
return rv;
}

bool isAggregate() const { return hasLV || rv.isAggregate(); }
};

class CallArgList : public llvm::SmallVector<CallArg, 8> {
Expand Down
7 changes: 0 additions & 7 deletions clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,13 @@
#define LLVM_CLANG_CIR_CIRGENFUNCTIONINFO_H

#include "clang/AST/CanonicalType.h"
#include "clang/CIR/ABIArgInfo.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/Support/TrailingObjects.h"

namespace clang::CIRGen {

struct CIRGenFunctionInfoArgInfo {
CanQualType type;
cir::ABIArgInfo info;
};

class CIRGenFunctionInfo final
Expand Down Expand Up @@ -77,11 +75,6 @@ class CIRGenFunctionInfo final
unsigned arg_size() const { return numArgs; }

CanQualType getReturnType() const { return getArgsBuffer()[0].type; }

cir::ABIArgInfo &getReturnInfo() { return getArgsBuffer()[0].info; }
const cir::ABIArgInfo &getReturnInfo() const {
return getArgsBuffer()[0].info;
}
};

} // namespace clang::CIRGen
Expand Down
22 changes: 0 additions & 22 deletions clang/lib/CIR/CodeGen/CIRGenTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -538,27 +538,5 @@ const CIRGenFunctionInfo &CIRGenTypes::arrangeCIRFunctionInfo(
fi = CIRGenFunctionInfo::create(returnType, argTypes);
functionInfos.InsertNode(fi, insertPos);

bool inserted = functionsBeingProcessed.insert(fi).second;
(void)inserted;
assert(inserted && "Are functions being processed recursively?");

assert(!cir::MissingFeatures::opCallCallConv());
getABIInfo().computeInfo(*fi);

// Loop over all of the computed argument and return value info. If any of
// them are direct or extend without a specified coerce type, specify the
// default now.
cir::ABIArgInfo &retInfo = fi->getReturnInfo();
if (retInfo.canHaveCoerceToType() && retInfo.getCoerceToType() == nullptr)
retInfo.setCoerceToType(convertType(fi->getReturnType()));

for (CIRGenFunctionInfoArgInfo &i : fi->arguments())
if (i.info.canHaveCoerceToType() && i.info.getCoerceToType() == nullptr)
i.info.setCoerceToType(convertType(i.type));

bool erased = functionsBeingProcessed.erase(fi);
(void)erased;
assert(erased && "Not in set?");

return *fi;
}
1 change: 1 addition & 0 deletions clang/lib/CIR/CodeGen/CIRGenValue.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class RValue {

public:
bool isScalar() const { return v1.getInt() == Scalar; }
bool isAggregate() const { return v1.getInt() == Aggregate; }

/// Return the mlir::Value of this scalar value.
mlir::Value getScalarVal() const {
Expand Down
21 changes: 0 additions & 21 deletions clang/lib/CIR/CodeGen/TargetInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ namespace {
class X8664ABIInfo : public ABIInfo {
public:
X8664ABIInfo(CIRGenTypes &cgt) : ABIInfo(cgt) {}

void computeInfo(CIRGenFunctionInfo &funcInfo) const override;
};

class X8664TargetCIRGenInfo : public TargetCIRGenInfo {
Expand All @@ -28,25 +26,6 @@ class X8664TargetCIRGenInfo : public TargetCIRGenInfo {

} // namespace

void X8664ABIInfo::computeInfo(CIRGenFunctionInfo &funcInfo) const {
// Top level CIR has unlimited arguments and return types. Lowering for ABI
// specific concerns should happen during a lowering phase. Assume everything
// is direct for now.
for (CIRGenFunctionInfoArgInfo &info : funcInfo.arguments()) {
if (testIfIsVoidTy(info.type))
info.info = cir::ABIArgInfo::getIgnore();
else
info.info = cir::ABIArgInfo::getDirect(cgt.convertType(info.type));
}

CanQualType retTy = funcInfo.getReturnType();
if (testIfIsVoidTy(retTy))
funcInfo.getReturnInfo() = cir::ABIArgInfo::getIgnore();
else
funcInfo.getReturnInfo() =
cir::ABIArgInfo::getDirect(cgt.convertType(retTy));
}

std::unique_ptr<TargetCIRGenInfo>
clang::CIRGen::createX8664TargetCIRGenInfo(CIRGenTypes &cgt) {
return std::make_unique<X8664TargetCIRGenInfo>(cgt);
Expand Down