Add support for 'unmasked' function qualifier.

This commit is contained in:
Matt Pharr
2012-06-20 15:36:00 -07:00
parent 46716aada3
commit 007a734595
9 changed files with 91 additions and 53 deletions

View File

@@ -1131,10 +1131,7 @@ PointerType::LLVMType(llvm::LLVMContext *ctx) const {
llvm::Type *ptype = NULL;
const FunctionType *ftype = CastType<FunctionType>(baseType);
if (ftype != NULL)
// Get the type of the function variant that takes the mask as the
// last parameter--i.e. we don't allow taking function pointers of
// exported functions.
ptype = llvm::PointerType::get(ftype->LLVMFunctionType(ctx, true), 0);
ptype = llvm::PointerType::get(ftype->LLVMFunctionType(ctx), 0);
else {
if (baseType == AtomicType::Void)
ptype = LLVMTypes::VoidPointerType;
@@ -2625,10 +2622,12 @@ ReferenceType::GetDIType(llvm::DIDescriptor scope) const {
///////////////////////////////////////////////////////////////////////////
// FunctionType
FunctionType::FunctionType(const Type *r, const llvm::SmallVector<const Type *, 8> &a,
FunctionType::FunctionType(const Type *r,
const llvm::SmallVector<const Type *, 8> &a,
SourcePos p)
: Type(FUNCTION_TYPE), isTask(false), isExported(false), isExternC(false),
returnType(r), paramTypes(a), paramNames(llvm::SmallVector<std::string, 8>(a.size(), "")),
isUnmasked(false), returnType(r), paramTypes(a),
paramNames(llvm::SmallVector<std::string, 8>(a.size(), "")),
paramDefaults(llvm::SmallVector<Expr *, 8>(a.size(), NULL)),
paramPositions(llvm::SmallVector<SourcePos, 8>(a.size(), p)) {
Assert(returnType != NULL);
@@ -2637,13 +2636,15 @@ FunctionType::FunctionType(const Type *r, const llvm::SmallVector<const Type *,
}
FunctionType::FunctionType(const Type *r, const llvm::SmallVector<const Type *, 8> &a,
FunctionType::FunctionType(const Type *r,
const llvm::SmallVector<const Type *, 8> &a,
const llvm::SmallVector<std::string, 8> &an,
const llvm::SmallVector<Expr *, 8> &ad,
const llvm::SmallVector<SourcePos, 8> &ap,
bool it, bool is, bool ec)
: Type(FUNCTION_TYPE), isTask(it), isExported(is), isExternC(ec), returnType(r),
paramTypes(a), paramNames(an), paramDefaults(ad), paramPositions(ap) {
bool it, bool is, bool ec, bool ium)
: Type(FUNCTION_TYPE), isTask(it), isExported(is), isExternC(ec),
isUnmasked(ium), returnType(r), paramTypes(a), paramNames(an),
paramDefaults(ad), paramPositions(ap) {
Assert(paramTypes.size() == paramNames.size() &&
paramNames.size() == paramDefaults.size() &&
paramDefaults.size() == paramPositions.size());
@@ -2743,7 +2744,7 @@ FunctionType::ResolveUnboundVariability(Variability v) const {
FunctionType *ret = new FunctionType(rt, pt, paramNames, paramDefaults,
paramPositions, isTask, isExported,
isExternC);
isExternC, isUnmasked);
ret->isSafe = isSafe;
ret->costOverride = costOverride;
@@ -2784,6 +2785,9 @@ FunctionType::GetString() const {
std::string
FunctionType::Mangle() const {
std::string ret = "___";
if (isUnmasked)
ret += "UM_";
for (unsigned int i = 0; i < paramTypes.size(); ++i)
if (paramTypes[i] == NULL)
Assert(m->errorCount > 0);
@@ -2865,6 +2869,8 @@ FunctionType::GetReturnTypeString() const {
ret += "export ";
if (isExternC)
ret += "extern \"C\" ";
if (isUnmasked)
ret += "unmasked ";
if (isSafe)
ret += "/*safe*/ ";
if (costOverride > 0) {
@@ -2872,14 +2878,15 @@ FunctionType::GetReturnTypeString() const {
sprintf(buf, "/*cost=%d*/ ", costOverride);
ret += buf;
}
return ret + returnType->GetString();
}
llvm::FunctionType *
FunctionType::LLVMFunctionType(llvm::LLVMContext *ctx, bool includeMask) const {
FunctionType::LLVMFunctionType(llvm::LLVMContext *ctx, bool removeMask) const {
if (isTask == true)
Assert(includeMask == true);
Assert(removeMask == false);
// Get the LLVM Type *s for the function arguments
std::vector<llvm::Type *> llvmArgTypes;
@@ -2899,7 +2906,7 @@ FunctionType::LLVMFunctionType(llvm::LLVMContext *ctx, bool includeMask) const {
}
// And add the function mask, if asked for
if (includeMask)
if (!(removeMask || isUnmasked))
llvmArgTypes.push_back(LLVMTypes::MaskType);
std::vector<llvm::Type *> callTypes;
@@ -3263,7 +3270,8 @@ lCheckTypeEquality(const Type *a, const Type *b, bool ignoreConst) {
if (fta->isTask != ftb->isTask ||
fta->isExported != ftb->isExported ||
fta->isExternC != ftb->isExternC)
fta->isExternC != ftb->isExternC ||
fta->isUnmasked != ftb->isUnmasked)
return false;
if (fta->GetNumParameters() != ftb->GetNumParameters())