summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
authorOwen Anderson <resistor@mac.com>2015-05-26 23:48:40 +0000
committerOwen Anderson <resistor@mac.com>2015-05-26 23:48:40 +0000
commit85fa7d5037fed8191ef67c2b4d954218b942a7d1 (patch)
tree7e3c7d6e771cbbe3926c0411cd3d1ee678a493b6 /llvm
parent3abb86da627a01b1e2091c08a9117dc273f9473f (diff)
downloadbcm5719-llvm-85fa7d5037fed8191ef67c2b4d954218b942a7d1.tar.gz
bcm5719-llvm-85fa7d5037fed8191ef67c2b4d954218b942a7d1.zip
Add initial support for the convergent attribute.
llvm-svn: 238264
Diffstat (limited to 'llvm')
-rw-r--r--llvm/docs/LangRef.rst7
-rw-r--r--llvm/include/llvm/Bitcode/LLVMBitCodes.h3
-rw-r--r--llvm/include/llvm/IR/Attributes.h1
-rw-r--r--llvm/include/llvm/IR/Function.h10
-rw-r--r--llvm/include/llvm/IR/Intrinsics.td5
-rw-r--r--llvm/lib/AsmParser/LLLexer.cpp1
-rw-r--r--llvm/lib/AsmParser/LLParser.cpp1
-rw-r--r--llvm/lib/AsmParser/LLToken.h1
-rw-r--r--llvm/lib/Bitcode/Reader/BitcodeReader.cpp2
-rw-r--r--llvm/lib/Bitcode/Writer/BitcodeWriter.cpp2
-rw-r--r--llvm/lib/IR/Attributes.cpp3
-rw-r--r--llvm/lib/IR/Verifier.cpp3
-rw-r--r--llvm/test/Bitcode/attributes.ll10
-rw-r--r--llvm/utils/TableGen/CodeGenIntrinsics.h3
-rw-r--r--llvm/utils/TableGen/CodeGenTarget.cpp3
-rw-r--r--llvm/utils/TableGen/IntrinsicEmitter.cpp11
16 files changed, 61 insertions, 5 deletions
diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index 1ee16f866d6..397d5fe3756 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -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
diff --git a/llvm/include/llvm/Bitcode/LLVMBitCodes.h b/llvm/include/llvm/Bitcode/LLVMBitCodes.h
index fe6d3662954..3a6b5c704d1 100644
--- a/llvm/include/llvm/Bitcode/LLVMBitCodes.h
+++ b/llvm/include/llvm/Bitcode/LLVMBitCodes.h
@@ -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 {
diff --git a/llvm/include/llvm/IR/Attributes.h b/llvm/include/llvm/IR/Attributes.h
index 86af13f864f..e2a0a7ee395 100644
--- a/llvm/include/llvm/IR/Attributes.h
+++ b/llvm/include/llvm/IR/Attributes.h
@@ -73,6 +73,7 @@ public:
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.
diff --git a/llvm/include/llvm/IR/Function.h b/llvm/include/llvm/IR/Function.h
index 73f22b129ad..6c228eae633 100644
--- a/llvm/include/llvm/IR/Function.h
+++ b/llvm/include/llvm/IR/Function.h
@@ -308,6 +308,16 @@ public:
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 {
diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td
index 8f772b5193b..8f6cdebb049 100644
--- a/llvm/include/llvm/IR/Intrinsics.td
+++ b/llvm/include/llvm/IR/Intrinsics.td
@@ -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.
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/AsmParser/LLLexer.cpp b/llvm/lib/AsmParser/LLLexer.cpp
index a72f713c490..05c24285028 100644
--- a/llvm/lib/AsmParser/LLLexer.cpp
+++ b/llvm/lib/AsmParser/LLLexer.cpp
@@ -597,6 +597,7 @@ lltok::Kind LLLexer::LexIdentifier() {
KEYWORD(byval);
KEYWORD(inalloca);
KEYWORD(cold);
+ KEYWORD(convergent);
KEYWORD(dereferenceable);
KEYWORD(dereferenceable_or_null);
KEYWORD(inlinehint);
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index 713aba790ef..a52e20fb35b 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -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;
diff --git a/llvm/lib/AsmParser/LLToken.h b/llvm/lib/AsmParser/LLToken.h
index 2bdc53b3e2e..c47f5e1654d 100644
--- a/llvm/lib/AsmParser/LLToken.h
+++ b/llvm/lib/AsmParser/LLToken.h
@@ -105,6 +105,7 @@ namespace lltok {
kw_byval,
kw_inalloca,
kw_cold,
+ kw_convergent,
kw_dereferenceable,
kw_dereferenceable_or_null,
kw_inlinehint,
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
index 3f21bb9fbac..95cf51f1419 100644
--- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -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:
diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
index 3a539e12926..97caefb4c49 100644
--- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -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:
diff --git a/llvm/lib/IR/Attributes.cpp b/llvm/lib/IR/Attributes.cpp
index 55d3122bbd8..fef05c8f92d 100644
--- a/llvm/lib/IR/Attributes.cpp
+++ b/llvm/lib/IR/Attributes.cpp
@@ -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))
@@ -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;
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 635e8efa11b..5ed137abd0e 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -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);
diff --git a/llvm/test/Bitcode/attributes.ll b/llvm/test/Bitcode/attributes.ll
index 9fbdfeb0ef0..cae6a2e01e6 100644
--- a/llvm/test/Bitcode/attributes.ll
+++ b/llvm/test/Bitcode/attributes.ll
@@ -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;
}
@@ -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 }
@@ -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 }
diff --git a/llvm/utils/TableGen/CodeGenIntrinsics.h b/llvm/utils/TableGen/CodeGenIntrinsics.h
index 1f1adf11fb3..f4055571b1c 100644
--- a/llvm/utils/TableGen/CodeGenIntrinsics.h
+++ b/llvm/utils/TableGen/CodeGenIntrinsics.h
@@ -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,
diff --git a/llvm/utils/TableGen/CodeGenTarget.cpp b/llvm/utils/TableGen/CodeGenTarget.cpp
index da54a75713b..076537002a6 100644
--- a/llvm/utils/TableGen/CodeGenTarget.cpp
+++ b/llvm/utils/TableGen/CodeGenTarget.cpp
@@ -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_")
@@ -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")) {
diff --git a/llvm/utils/TableGen/IntrinsicEmitter.cpp b/llvm/utils/TableGen/IntrinsicEmitter.cpp
index 1a2555ebbf6..3f62f205fe5 100644
--- a/llvm/utils/TableGen/IntrinsicEmitter.cpp
+++ b/llvm/utils/TableGen/IntrinsicEmitter.cpp
@@ -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);
@@ -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) {
@@ -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;
OpenPOWER on IntegriCloud