Skip to content

Commit

Permalink
Add initial support for the convergent attribute.
Browse files Browse the repository at this point in the history
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@238264 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
resistor committed May 26, 2015
1 parent 1c74d47 commit 13146c7
Show file tree
Hide file tree
Showing 16 changed files with 61 additions and 5 deletions.
7 changes: 7 additions & 0 deletions docs/LangRef.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1196,6 +1196,13 @@ example:
computing edge weights, basic blocks post-dominated by a cold
function call are also considered to be cold; and, thus, given low
weight.
``convergent``
This attribute indicates that the callee is dependent on a convergent
thread execution pattern under certain parallel execution models.
Transformations that are execution model agnostic may only move or
tranform this call if the final location is control equivalent to its
original position in the program, where control equivalence is defined as
A dominates B and B post-dominates A, or vice versa.
``inlinehint``
This attribute indicates that the source code contained a hint that
inlining this function is desirable (such as the "inline" keyword in
Expand Down
3 changes: 2 additions & 1 deletion include/llvm/Bitcode/LLVMBitCodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,8 @@ namespace bitc {
ATTR_KIND_NON_NULL = 39,
ATTR_KIND_JUMP_TABLE = 40,
ATTR_KIND_DEREFERENCEABLE = 41,
ATTR_KIND_DEREFERENCEABLE_OR_NULL = 42
ATTR_KIND_DEREFERENCEABLE_OR_NULL = 42,
ATTR_KIND_CONVERGENT = 43
};

enum ComdatSelectionKindCodes {
Expand Down
1 change: 1 addition & 0 deletions include/llvm/IR/Attributes.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ class Attribute {
ByVal, ///< Pass structure by value
InAlloca, ///< Pass structure in an alloca
Cold, ///< Marks function as being in a cold path.
Convergent, ///< Can only be moved to control-equivalent blocks
InlineHint, ///< Source said inlining was desirable
InReg, ///< Force argument to be passed in register
JumpTable, ///< Build jump-instruction tables and replace refs.
Expand Down
10 changes: 10 additions & 0 deletions include/llvm/IR/Function.h
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,16 @@ class Function : public GlobalObject, public ilist_node<Function> {
addFnAttr(Attribute::NoDuplicate);
}

/// @brief Determine if the call is convergent.
bool isConvergent() const {
return AttributeSets.hasAttribute(AttributeSet::FunctionIndex,
Attribute::Convergent);
}
void setConvergent() {
addFnAttr(Attribute::Convergent);
}


/// @brief True if the ABI mandates (or the user requested) that this
/// function be in a unwind table.
bool hasUWTable() const {
Expand Down
5 changes: 5 additions & 0 deletions include/llvm/IR/Intrinsics.td
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,11 @@ def IntrNoReturn : IntrinsicProperty;
// Parallels the noduplicate attribute on LLVM IR functions.
def IntrNoDuplicate : IntrinsicProperty;

// IntrConvergent - Calls to this intrinsic are convergent and may only be
// moved to control equivalent blocks.
// Parallels the convergent attribute on LLVM IR functions.
def IntrConvergent : IntrinsicProperty;

//===----------------------------------------------------------------------===//
// Types used by intrinsics.
//===----------------------------------------------------------------------===//
Expand Down
1 change: 1 addition & 0 deletions lib/AsmParser/LLLexer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -597,6 +597,7 @@ lltok::Kind LLLexer::LexIdentifier() {
KEYWORD(byval);
KEYWORD(inalloca);
KEYWORD(cold);
KEYWORD(convergent);
KEYWORD(dereferenceable);
KEYWORD(dereferenceable_or_null);
KEYWORD(inlinehint);
Expand Down
1 change: 1 addition & 0 deletions lib/AsmParser/LLParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -937,6 +937,7 @@ bool LLParser::ParseFnAttributeValuePairs(AttrBuilder &B,
case lltok::kw_alwaysinline: B.addAttribute(Attribute::AlwaysInline); break;
case lltok::kw_builtin: B.addAttribute(Attribute::Builtin); break;
case lltok::kw_cold: B.addAttribute(Attribute::Cold); break;
case lltok::kw_convergent: B.addAttribute(Attribute::Convergent); break;
case lltok::kw_inlinehint: B.addAttribute(Attribute::InlineHint); break;
case lltok::kw_jumptable: B.addAttribute(Attribute::JumpTable); break;
case lltok::kw_minsize: B.addAttribute(Attribute::MinSize); break;
Expand Down
1 change: 1 addition & 0 deletions lib/AsmParser/LLToken.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ namespace lltok {
kw_byval,
kw_inalloca,
kw_cold,
kw_convergent,
kw_dereferenceable,
kw_dereferenceable_or_null,
kw_inlinehint,
Expand Down
2 changes: 2 additions & 0 deletions lib/Bitcode/Reader/BitcodeReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1095,6 +1095,8 @@ static Attribute::AttrKind GetAttrFromCode(uint64_t Code) {
return Attribute::InAlloca;
case bitc::ATTR_KIND_COLD:
return Attribute::Cold;
case bitc::ATTR_KIND_CONVERGENT:
return Attribute::Convergent;
case bitc::ATTR_KIND_INLINE_HINT:
return Attribute::InlineHint;
case bitc::ATTR_KIND_IN_REG:
Expand Down
2 changes: 2 additions & 0 deletions lib/Bitcode/Writer/BitcodeWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,8 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) {
return bitc::ATTR_KIND_BUILTIN;
case Attribute::ByVal:
return bitc::ATTR_KIND_BY_VAL;
case Attribute::Convergent:
return bitc::ATTR_KIND_CONVERGENT;
case Attribute::InAlloca:
return bitc::ATTR_KIND_IN_ALLOCA;
case Attribute::Cold:
Expand Down
3 changes: 3 additions & 0 deletions lib/IR/Attributes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,8 @@ std::string Attribute::getAsString(bool InAttrGrp) const {
return "builtin";
if (hasAttribute(Attribute::ByVal))
return "byval";
if (hasAttribute(Attribute::Convergent))
return "convergent";
if (hasAttribute(Attribute::InAlloca))
return "inalloca";
if (hasAttribute(Attribute::InlineHint))
Expand Down Expand Up @@ -434,6 +436,7 @@ uint64_t AttributeImpl::getAttrMask(Attribute::AttrKind Val) {
case Attribute::InAlloca: return 1ULL << 43;
case Attribute::NonNull: return 1ULL << 44;
case Attribute::JumpTable: return 1ULL << 45;
case Attribute::Convergent: return 1ULL << 46;
case Attribute::Dereferenceable:
llvm_unreachable("dereferenceable attribute not supported in raw format");
break;
Expand Down
3 changes: 2 additions & 1 deletion lib/IR/Verifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1268,7 +1268,8 @@ void Verifier::VerifyAttributeTypes(AttributeSet Attrs, unsigned Idx,
I->getKindAsEnum() == Attribute::NoBuiltin ||
I->getKindAsEnum() == Attribute::Cold ||
I->getKindAsEnum() == Attribute::OptimizeNone ||
I->getKindAsEnum() == Attribute::JumpTable) {
I->getKindAsEnum() == Attribute::JumpTable ||
I->getKindAsEnum() == Attribute::Convergent) {
if (!isFunction) {
CheckFailed("Attribute '" + I->getAsString() +
"' only applies to functions!", V);
Expand Down
10 changes: 8 additions & 2 deletions test/Bitcode/attributes.ll
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ define void @f34()
; CHECK: define void @f34()
{
call void @nobuiltin() nobuiltin
; CHECK: call void @nobuiltin() #25
; CHECK: call void @nobuiltin() #26
ret void;
}

Expand Down Expand Up @@ -251,6 +251,11 @@ define dereferenceable_or_null(8) i8* @f42(i8* dereferenceable_or_null(8) %foo)
ret i8* %foo
}

; CHECK: define void @f43() #25
define void @f43() convergent {
ret void
}

; CHECK: attributes #0 = { noreturn }
; CHECK: attributes #1 = { nounwind }
; CHECK: attributes #2 = { readnone }
Expand All @@ -276,4 +281,5 @@ define dereferenceable_or_null(8) i8* @f42(i8* dereferenceable_or_null(8) %foo)
; CHECK: attributes #22 = { minsize }
; CHECK: attributes #23 = { noinline optnone }
; CHECK: attributes #24 = { jumptable }
; CHECK: attributes #25 = { nobuiltin }
; CHECK: attributes #25 = { convergent }
; CHECK: attributes #26 = { nobuiltin }
3 changes: 3 additions & 0 deletions utils/TableGen/CodeGenIntrinsics.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ namespace llvm {
/// isNoReturn - True if the intrinsic is no-return.
bool isNoReturn;

/// isConvergent - True if the intrinsic is marked as convergent.
bool isConvergent;

enum ArgAttribute {
NoCapture,
ReadOnly,
Expand Down
3 changes: 3 additions & 0 deletions utils/TableGen/CodeGenTarget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,7 @@ CodeGenIntrinsic::CodeGenIntrinsic(Record *R) {
canThrow = false;
isNoReturn = false;
isNoDuplicate = false;
isConvergent = false;

if (DefName.size() <= 4 ||
std::string(DefName.begin(), DefName.begin() + 4) != "int_")
Expand Down Expand Up @@ -574,6 +575,8 @@ CodeGenIntrinsic::CodeGenIntrinsic(Record *R) {
canThrow = true;
else if (Property->getName() == "IntrNoDuplicate")
isNoDuplicate = true;
else if (Property->getName() == "IntrConvergent")
isConvergent = true;
else if (Property->getName() == "IntrNoReturn")
isNoReturn = true;
else if (Property->isSubClassOf("NoCapture")) {
Expand Down
11 changes: 10 additions & 1 deletion utils/TableGen/IntrinsicEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,9 @@ struct AttributeComparator {
if (L->isNoReturn != R->isNoReturn)
return R->isNoReturn;

if (L->isConvergent != R->isConvergent)
return R->isConvergent;

// Try to order by readonly/readnone attribute.
ModRefKind LK = getModRefKind(*L);
ModRefKind RK = getModRefKind(*R);
Expand Down Expand Up @@ -649,7 +652,7 @@ EmitAttributes(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS) {
ModRefKind modRef = getModRefKind(intrinsic);

if (!intrinsic.canThrow || modRef || intrinsic.isNoReturn ||
intrinsic.isNoDuplicate) {
intrinsic.isNoDuplicate || intrinsic.isConvergent) {
OS << " const Attribute::AttrKind Atts[] = {";
bool addComma = false;
if (!intrinsic.canThrow) {
Expand All @@ -668,6 +671,12 @@ EmitAttributes(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS) {
OS << "Attribute::NoDuplicate";
addComma = true;
}
if (intrinsic.isConvergent) {
if (addComma)
OS << ",";
OS << "Attribute::Convergent";
addComma = true;
}

switch (modRef) {
case MRK_none: break;
Expand Down

0 comments on commit 13146c7

Please sign in to comment.