|
14 | 14 | #include "GCNSubtarget.h" |
15 | 15 | #include "Utils/AMDGPUBaseInfo.h" |
16 | 16 | #include "llvm/Analysis/CycleAnalysis.h" |
| 17 | +#include "llvm/Analysis/UniformityAnalysis.h" |
17 | 18 | #include "llvm/CodeGen/TargetPassConfig.h" |
18 | 19 | #include "llvm/IR/IntrinsicsAMDGPU.h" |
19 | 20 | #include "llvm/IR/IntrinsicsR600.h" |
@@ -1014,6 +1015,97 @@ struct AAAMDGPUNoAGPR |
1014 | 1015 |
|
1015 | 1016 | const char AAAMDGPUNoAGPR::ID = 0; |
1016 | 1017 |
|
| 1018 | +struct AAAMDGPUInreg |
| 1019 | + : public IRAttribute<Attribute::InReg, |
| 1020 | + StateWrapper<BooleanState, AbstractAttribute>, |
| 1021 | + AAAMDGPUInreg> { |
| 1022 | + AAAMDGPUInreg(const IRPosition &IRP, Attributor &A) : IRAttribute(IRP) {} |
| 1023 | + |
| 1024 | + /// Create an abstract attribute view for the position \p IRP. |
| 1025 | + static AAAMDGPUInreg &createForPosition(const IRPosition &IRP, Attributor &A); |
| 1026 | + |
| 1027 | + /// See AbstractAttribute::getName() |
| 1028 | + const std::string getName() const override { return "AAAMDGPUInreg"; } |
| 1029 | + |
| 1030 | + const std::string getAsStr(Attributor *A) const override { |
| 1031 | + return getAssumed() ? "inreg" : "non-inreg"; |
| 1032 | + } |
| 1033 | + |
| 1034 | + void trackStatistics() const override {} |
| 1035 | + |
| 1036 | + /// See AbstractAttribute::getIdAddr() |
| 1037 | + const char *getIdAddr() const override { return &ID; } |
| 1038 | + |
| 1039 | + /// This function should return true if the type of the \p AA is AAAMDGPUInreg |
| 1040 | + static bool classof(const AbstractAttribute *AA) { |
| 1041 | + return (AA->getIdAddr() == &ID); |
| 1042 | + } |
| 1043 | + |
| 1044 | + /// Unique ID (due to the unique address) |
| 1045 | + static const char ID; |
| 1046 | +}; |
| 1047 | + |
| 1048 | +const char AAAMDGPUInreg::ID = 0; |
| 1049 | + |
| 1050 | +namespace { |
| 1051 | + |
| 1052 | +struct AAAMDGPUInregArgument : public AAAMDGPUInreg { |
| 1053 | + AAAMDGPUInregArgument(const IRPosition &IRP, Attributor &A) |
| 1054 | + : AAAMDGPUInreg(IRP, A) {} |
| 1055 | + |
| 1056 | + void initialize(Attributor &A) override { |
| 1057 | + if (getAssociatedArgument()->hasAttribute(Attribute::InReg)) |
| 1058 | + indicateOptimisticFixpoint(); |
| 1059 | + } |
| 1060 | + |
| 1061 | + ChangeStatus updateImpl(Attributor &A) override { |
| 1062 | + unsigned ArgNo = getAssociatedArgument()->getArgNo(); |
| 1063 | + |
| 1064 | + auto Pred = [&](AbstractCallSite ACS) -> bool { |
| 1065 | + CallBase *CB = ACS.getInstruction(); |
| 1066 | + Value *V = CB->getArgOperandUse(ArgNo); |
| 1067 | + if (auto *G = dyn_cast<GlobalValue>(V)) |
| 1068 | + return true; |
| 1069 | + if (auto *I = dyn_cast<Instruction>(V)) { |
| 1070 | + auto AU = A.getInfoCache() |
| 1071 | + .getAnalysisResultForFunction<UniformityInfoAnalysis>( |
| 1072 | + *I->getFunction()); |
| 1073 | + return AU && AU->isUniform(I); |
| 1074 | + } |
| 1075 | + if (auto *Arg = dyn_cast<Argument>(V)) { |
| 1076 | + auto *AA = |
| 1077 | + A.getOrCreateAAFor<AAAMDGPUInreg>(IRPosition::argument(*Arg)); |
| 1078 | + return AA && AA->isValidState(); |
| 1079 | + } |
| 1080 | + // For unforeseen cases, we need to assume it is not uniform thus not |
| 1081 | + // qualified for inreg. |
| 1082 | + return false; |
| 1083 | + }; |
| 1084 | + |
| 1085 | + bool UsedAssumedInformation = false; |
| 1086 | + if (!A.checkForAllCallSites(Pred, *this, /*RequireAllCallSites=*/true, |
| 1087 | + UsedAssumedInformation)) |
| 1088 | + return indicatePessimisticFixpoint(); |
| 1089 | + |
| 1090 | + if (!UsedAssumedInformation) |
| 1091 | + return indicateOptimisticFixpoint(); |
| 1092 | + |
| 1093 | + return ChangeStatus::UNCHANGED; |
| 1094 | + } |
| 1095 | +}; |
| 1096 | + |
| 1097 | +} // namespace |
| 1098 | + |
| 1099 | +AAAMDGPUInreg &AAAMDGPUInreg::createForPosition(const IRPosition &IRP, |
| 1100 | + Attributor &A) { |
| 1101 | + switch (IRP.getPositionKind()) { |
| 1102 | + case IRPosition::IRP_ARGUMENT: |
| 1103 | + return *new (A.Allocator) AAAMDGPUInregArgument(IRP, A); |
| 1104 | + default: |
| 1105 | + llvm_unreachable("not a valid position for AAAMDGPUInreg"); |
| 1106 | + } |
| 1107 | +} |
| 1108 | + |
1017 | 1109 | static void addPreloadKernArgHint(Function &F, TargetMachine &TM) { |
1018 | 1110 | const GCNSubtarget &ST = TM.getSubtarget<GCNSubtarget>(F); |
1019 | 1111 | for (unsigned I = 0; |
@@ -1046,7 +1138,7 @@ static bool runImpl(Module &M, AnalysisGetter &AG, TargetMachine &TM, |
1046 | 1138 | &AAAMDWavesPerEU::ID, &AAAMDGPUNoAGPR::ID, &AACallEdges::ID, |
1047 | 1139 | &AAPointerInfo::ID, &AAPotentialConstantValues::ID, |
1048 | 1140 | &AAUnderlyingObjects::ID, &AAAddressSpace::ID, &AAIndirectCallInfo::ID, |
1049 | | - &AAInstanceInfo::ID}); |
| 1141 | + &AAInstanceInfo::ID, &AAAMDGPUInreg::ID}); |
1050 | 1142 |
|
1051 | 1143 | AttributorConfig AC(CGUpdater); |
1052 | 1144 | AC.IsClosedWorldModule = Options.IsClosedWorld; |
@@ -1090,6 +1182,11 @@ static bool runImpl(Module &M, AnalysisGetter &AG, TargetMachine &TM, |
1090 | 1182 | IRPosition::value(*SI->getPointerOperand())); |
1091 | 1183 | } |
1092 | 1184 | } |
| 1185 | + |
| 1186 | + if (F.getCallingConv() != CallingConv::AMDGPU_KERNEL) { |
| 1187 | + for (auto &Arg : F.args()) |
| 1188 | + A.getOrCreateAAFor<AAAMDGPUInreg>(IRPosition::argument(Arg)); |
| 1189 | + } |
1093 | 1190 | } |
1094 | 1191 |
|
1095 | 1192 | ChangeStatus Change = A.run(); |
@@ -1118,6 +1215,7 @@ class AMDGPUAttributorLegacy : public ModulePass { |
1118 | 1215 |
|
1119 | 1216 | void getAnalysisUsage(AnalysisUsage &AU) const override { |
1120 | 1217 | AU.addRequired<CycleInfoWrapperPass>(); |
| 1218 | + AU.addRequired<UniformityInfoWrapperPass>(); |
1121 | 1219 | } |
1122 | 1220 |
|
1123 | 1221 | StringRef getPassName() const override { return "AMDGPU Attributor"; } |
|
0 commit comments