Skip to content

Commit 2e5243d

Browse files
committed
Introduce DisjointAgents fn attribute/intrinsic property.
This patch attempts to generalise this workaround: intel#1334
1 parent 6f620a4 commit 2e5243d

File tree

17 files changed

+49
-14
lines changed

17 files changed

+49
-14
lines changed

llvm/include/llvm/AsmParser/LLToken.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ enum Kind {
188188
kw_inalloca,
189189
kw_cold,
190190
kw_convergent,
191+
kw_disjoint_agents,
191192
kw_dereferenceable,
192193
kw_dereferenceable_or_null,
193194
kw_disable_sanitizer_instrumentation,

llvm/include/llvm/Bitcode/LLVMBitCodes.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -672,6 +672,7 @@ enum AttributeKindCodes {
672672
ATTR_KIND_NO_SANITIZE_COVERAGE = 76,
673673
ATTR_KIND_ELEMENTTYPE = 77,
674674
ATTR_KIND_DISABLE_SANITIZER_INSTRUMENTATION = 78,
675+
ATTR_KIND_DISJOINT_AGENTS = 79,
675676
};
676677

677678
enum ComdatSelectionKindCodes {

llvm/include/llvm/IR/Attributes.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ def Cold : EnumAttr<"cold", [FnAttr]>;
7676
/// Can only be moved to control-equivalent blocks.
7777
def Convergent : EnumAttr<"convergent", [FnAttr]>;
7878

79+
/// TODO: JKB: Document
80+
def DisjointAgents : EnumAttr<"disjoint_agents", [FnAttr]>;
81+
7982
/// Marks function as being in a hot path and frequently called.
8083
def Hot: EnumAttr<"hot", [FnAttr]>;
8184

llvm/include/llvm/IR/Function.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,17 @@ class LLVM_EXTERNAL_VISIBILITY Function : public GlobalObject,
589589
removeFnAttr(Attribute::Convergent);
590590
}
591591

592+
/// Determine if the call has disjoint agents.
593+
bool isDisjointAgents() const {
594+
return hasFnAttribute(Attribute::DisjointAgents);
595+
}
596+
void setDisjointAgents() {
597+
addFnAttr(Attribute::DisjointAgents);
598+
}
599+
void setNotDisjointAgents() {
600+
removeFnAttr(Attribute::DisjointAgents);
601+
}
602+
592603
/// Determine if the call has sideeffects.
593604
bool isSpeculatable() const {
594605
return hasFnAttribute(Attribute::Speculatable);

llvm/include/llvm/IR/Intrinsics.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,9 @@ def IntrSpeculatable : IntrinsicProperty;
159159
// defined by the hasSideEffects property of the TableGen Instruction class.
160160
def IntrHasSideEffects : IntrinsicProperty;
161161

162+
// TODO: JKB: Document.
163+
def IntrDisjointAgents : IntrinsicProperty;
164+
162165
//===----------------------------------------------------------------------===//
163166
// Types used by intrinsics.
164167
//===----------------------------------------------------------------------===//

llvm/include/llvm/IR/IntrinsicsNVVM.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1251,7 +1251,7 @@ let TargetPrefix = "nvvm" in {
12511251
// The builtin for "bar.sync 0" is called __syncthreads. Unlike most of the
12521252
// intrinsics in this file, this one is a user-facing API.
12531253
def int_nvvm_barrier0 : GCCBuiltin<"__syncthreads">,
1254-
Intrinsic<[], [], [IntrConvergent]>;
1254+
Intrinsic<[], [], [IntrConvergent, IntrDisjointAgents]>;
12551255
// Synchronize all threads in the CTA at barrier 'n'.
12561256
def int_nvvm_barrier_n : GCCBuiltin<"__nvvm_bar_n">,
12571257
Intrinsic<[], [llvm_i32_ty], [IntrConvergent]>;

llvm/include/llvm/Target/Target.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -550,6 +550,7 @@ class Instruction : InstructionEncoding {
550550
bit hasCtrlDep = false; // Does this instruction r/w ctrl-flow chains?
551551
bit isNotDuplicable = false; // Is it unsafe to duplicate this instruction?
552552
bit isConvergent = false; // Is this instruction convergent?
553+
bit isDisjointAgents = false; // TODO: JKB: Document.
553554
bit isAuthenticated = false; // Does this instruction authenticate a pointer?
554555
bit isAsCheapAsAMove = false; // As cheap (or cheaper) than a move instruction.
555556
bit hasExtraSrcRegAllocReq = false; // Sources have special regalloc requirement?

llvm/lib/Analysis/GlobalsModRef.cpp

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -533,18 +533,14 @@ void GlobalsAAResult::AnalyzeCallGraph(CallGraph &CG, Module &M) {
533533
FI.addModRefInfo(ModRefInfo::ModRef);
534534
if (!F->onlyAccessesArgMemory())
535535
FI.setMayReadAnyGlobal();
536-
if (!F->isIntrinsic()) {
537-
KnowNothing = true;
538-
break;
539-
} else if (F->getName().contains("nvvm.barrier") or
540-
F->getName().contains("nvvm.membar")) {
536+
if (!F->isIntrinsic() || F->isDisjointAgents()) {
541537
// Even if it is an intrinsic, consider that nothing is known for
542-
// NVVM barrier itrinsics to prevent illegal optimizations.
543-
// This is a workaround for the bug on PTX target: barrier
544-
// intrinsics are implemented as llvm intrinsics, as result there
545-
// are cases when globals alias analysis can produce a result that
546-
// barrier doesn't modify internal global which causes illegal
547-
// reordering of memory accesses.
538+
// calls that interact with disjoint agents, such as NVVM barrier
539+
// itrinsics to prevent illegal optimizations.
540+
// For context in PTX barriers are implemented as llvm intrinsics,
541+
// as result there are cases when globals alias analysis can
542+
// produce a result that barrier doesn't modify internal global
543+
// which causes illegal reordering of memory accesses.
548544
KnowNothing = true;
549545
break;
550546
}

llvm/lib/Bitcode/Reader/BitcodeReader.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1228,6 +1228,7 @@ static uint64_t getRawAttributeMask(Attribute::AttrKind Val) {
12281228
case Attribute::Naked: return 1 << 24;
12291229
case Attribute::InlineHint: return 1 << 25;
12301230
case Attribute::StackAlignment: return 7 << 26;
1231+
case Attribute::DisjointAgents: return 1ULL << 28;
12311232
case Attribute::ReturnsTwice: return 1 << 29;
12321233
case Attribute::UWTable: return 1 << 30;
12331234
case Attribute::NonLazyBind: return 1U << 31;
@@ -1393,6 +1394,8 @@ static Attribute::AttrKind getAttrFromCode(uint64_t Code) {
13931394
return Attribute::Cold;
13941395
case bitc::ATTR_KIND_CONVERGENT:
13951396
return Attribute::Convergent;
1397+
case bitc::ATTR_KIND_DISJOINT_AGENTS:
1398+
return Attribute::DisjointAgents;
13961399
case bitc::ATTR_KIND_DISABLE_SANITIZER_INSTRUMENTATION:
13971400
return Attribute::DisableSanitizerInstrumentation;
13981401
case bitc::ATTR_KIND_ELEMENTTYPE:

llvm/lib/Bitcode/Writer/BitcodeWriter.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -622,6 +622,8 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) {
622622
return bitc::ATTR_KIND_BY_VAL;
623623
case Attribute::Convergent:
624624
return bitc::ATTR_KIND_CONVERGENT;
625+
case Attribute::DisjointAgents:
626+
return bitc::ATTR_KIND_DISJOINT_AGENTS;
625627
case Attribute::InAlloca:
626628
return bitc::ATTR_KIND_IN_ALLOCA;
627629
case Attribute::Cold:

llvm/lib/Transforms/Utils/CodeExtractor.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -901,6 +901,7 @@ Function *CodeExtractor::constructFunction(const ValueSet &inputs,
901901
case Attribute::Builtin:
902902
case Attribute::ByVal:
903903
case Attribute::Convergent:
904+
case Attribute::DisjointAgents:
904905
case Attribute::Dereferenceable:
905906
case Attribute::DereferenceableOrNull:
906907
case Attribute::ElementType:

llvm/utils/TableGen/CodeGenInstruction.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,7 @@ CodeGenInstruction::CodeGenInstruction(Record *R)
397397
isExtractSubreg = R->getValueAsBit("isExtractSubreg");
398398
isInsertSubreg = R->getValueAsBit("isInsertSubreg");
399399
isConvergent = R->getValueAsBit("isConvergent");
400+
isDisjointAgents = R->getValueAsBit("isDisjointAgents");
400401
hasNoSchedulingInfo = R->getValueAsBit("hasNoSchedulingInfo");
401402
FastISelShouldIgnore = R->getValueAsBit("FastISelShouldIgnore");
402403
variadicOpsAreDefs = R->getValueAsBit("variadicOpsAreDefs");

llvm/utils/TableGen/CodeGenInstruction.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,7 @@ template <typename T> class ArrayRef;
274274
bool isExtractSubreg : 1;
275275
bool isInsertSubreg : 1;
276276
bool isConvergent : 1;
277+
bool isDisjointAgents : 1;
277278
bool hasNoSchedulingInfo : 1;
278279
bool FastISelShouldIgnore : 1;
279280
bool hasChain : 1;

llvm/utils/TableGen/CodeGenIntrinsics.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,9 @@ struct CodeGenIntrinsic {
148148
// True if the intrinsic is marked as speculatable.
149149
bool isSpeculatable;
150150

151+
// TODO: JKB: Document.
152+
bool isDisjointAgents;
153+
151154
enum ArgAttrKind {
152155
NoCapture,
153156
NoAlias,

llvm/utils/TableGen/CodeGenTarget.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -907,7 +907,9 @@ void CodeGenIntrinsic::setProperty(Record *R) {
907907
unsigned ArgNo = R->getValueAsInt("ArgNo");
908908
uint64_t Align = R->getValueAsInt("Align");
909909
ArgumentAttributes.emplace_back(ArgNo, Alignment, Align);
910-
} else
910+
} else if (R->getName() == "IntrDisjointAgents")
911+
isDisjointAgents = true;
912+
else
911913
llvm_unreachable("Unknown property!");
912914
}
913915

llvm/utils/TableGen/InstrInfoEmitter.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -981,6 +981,7 @@ void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num,
981981
if (Inst.isExtractSubreg) OS << "|(1ULL<<MCID::ExtractSubreg)";
982982
if (Inst.isInsertSubreg) OS << "|(1ULL<<MCID::InsertSubreg)";
983983
if (Inst.isConvergent) OS << "|(1ULL<<MCID::Convergent)";
984+
if (Inst.isDisjointAgents) OS << "|(1ULL<<MCID::DisjointAgents)";
984985
if (Inst.variadicOpsAreDefs) OS << "|(1ULL<<MCID::VariadicOpsAreDefs)";
985986
if (Inst.isAuthenticated) OS << "|(1ULL<<MCID::Authenticated)";
986987

llvm/utils/TableGen/IntrinsicEmitter.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -611,6 +611,9 @@ struct AttributeComparator {
611611
if (L->hasSideEffects != R->hasSideEffects)
612612
return R->hasSideEffects;
613613

614+
if (L->isDisjointAgents != R->isDisjointAgents)
615+
return R->isDisjointAgents;
616+
614617
// Try to order by readonly/readnone attribute.
615618
CodeGenIntrinsic::ModRefBehavior LK = L->ModRef;
616619
CodeGenIntrinsic::ModRefBehavior RK = R->ModRef;
@@ -742,7 +745,7 @@ void IntrinsicEmitter::EmitAttributes(const CodeGenIntrinsicTable &Ints,
742745
Intrinsic.isNoReturn || Intrinsic.isNoSync || Intrinsic.isNoFree ||
743746
Intrinsic.isWillReturn || Intrinsic.isCold || Intrinsic.isNoDuplicate ||
744747
Intrinsic.isNoMerge || Intrinsic.isConvergent ||
745-
Intrinsic.isSpeculatable) {
748+
Intrinsic.isSpeculatable || Intrinsic.isDisjointAgents) {
746749
OS << " const Attribute::AttrKind Atts[] = {";
747750
ListSeparator LS(",");
748751
if (!Intrinsic.canThrow)
@@ -765,6 +768,8 @@ void IntrinsicEmitter::EmitAttributes(const CodeGenIntrinsicTable &Ints,
765768
OS << LS << "Attribute::Convergent";
766769
if (Intrinsic.isSpeculatable)
767770
OS << LS << "Attribute::Speculatable";
771+
if (Intrinsic.isDisjointAgents)
772+
OS << LS << "Attribute::DisjointAgents";
768773

769774
switch (Intrinsic.ModRef) {
770775
case CodeGenIntrinsic::NoMem:

0 commit comments

Comments
 (0)