|
14 | 14 | #include "GCNSubtarget.h"
|
15 | 15 | #include "Utils/AMDGPUBaseInfo.h"
|
16 | 16 | #include "llvm/Analysis/CycleAnalysis.h"
|
| 17 | +#include "llvm/Analysis/TargetTransformInfo.h" |
| 18 | +#include "llvm/Analysis/UniformityAnalysis.h" |
17 | 19 | #include "llvm/CodeGen/TargetPassConfig.h"
|
18 | 20 | #include "llvm/IR/IntrinsicsAMDGPU.h"
|
19 | 21 | #include "llvm/IR/IntrinsicsR600.h"
|
@@ -1299,6 +1301,104 @@ struct AAAMDGPUNoAGPR
|
1299 | 1301 |
|
1300 | 1302 | const char AAAMDGPUNoAGPR::ID = 0;
|
1301 | 1303 |
|
| 1304 | +struct AAAMDGPUUniform : public StateWrapper<BooleanState, AbstractAttribute> { |
| 1305 | + using Base = StateWrapper<BooleanState, AbstractAttribute>; |
| 1306 | + AAAMDGPUUniform(const IRPosition &IRP, Attributor &A) : Base(IRP) {} |
| 1307 | + |
| 1308 | + /// Create an abstract attribute view for the position \p IRP. |
| 1309 | + static AAAMDGPUUniform &createForPosition(const IRPosition &IRP, |
| 1310 | + Attributor &A); |
| 1311 | + |
| 1312 | + /// See AbstractAttribute::getName() |
| 1313 | + const std::string getName() const override { return "AAAMDGPUUniform"; } |
| 1314 | + |
| 1315 | + const std::string getAsStr(Attributor *A) const override { |
| 1316 | + return getAssumed() ? "inreg" : "non-inreg"; |
| 1317 | + } |
| 1318 | + |
| 1319 | + void trackStatistics() const override {} |
| 1320 | + |
| 1321 | + /// See AbstractAttribute::getIdAddr() |
| 1322 | + const char *getIdAddr() const override { return &ID; } |
| 1323 | + |
| 1324 | + /// This function should return true if the type of the \p AA is |
| 1325 | + /// AAAMDGPUUniform |
| 1326 | + static bool classof(const AbstractAttribute *AA) { |
| 1327 | + return (AA->getIdAddr() == &ID); |
| 1328 | + } |
| 1329 | + |
| 1330 | + /// Unique ID (due to the unique address) |
| 1331 | + static const char ID; |
| 1332 | +}; |
| 1333 | + |
| 1334 | +const char AAAMDGPUUniform::ID = 0; |
| 1335 | + |
| 1336 | +struct AAAMDGPUUniformArgument : public AAAMDGPUUniform { |
| 1337 | + AAAMDGPUUniformArgument(const IRPosition &IRP, Attributor &A) |
| 1338 | + : AAAMDGPUUniform(IRP, A) {} |
| 1339 | + |
| 1340 | + void initialize(Attributor &A) override { |
| 1341 | + assert( |
| 1342 | + !AMDGPU::isEntryFunctionCC(getAssociatedFunction()->getCallingConv())); |
| 1343 | + if (getAssociatedArgument()->hasAttribute(Attribute::InReg)) |
| 1344 | + indicateOptimisticFixpoint(); |
| 1345 | + } |
| 1346 | + |
| 1347 | + ChangeStatus updateImpl(Attributor &A) override { |
| 1348 | + unsigned ArgNo = getAssociatedArgument()->getArgNo(); |
| 1349 | + |
| 1350 | + auto isUniform = [&](AbstractCallSite ACS) -> bool { |
| 1351 | + CallBase *CB = ACS.getInstruction(); |
| 1352 | + Value *V = CB->getArgOperandUse(ArgNo); |
| 1353 | + if (isa<Constant>(V)) |
| 1354 | + return true; |
| 1355 | + Function *F = nullptr; |
| 1356 | + if (auto *Arg = dyn_cast<Argument>(V)) |
| 1357 | + F = Arg->getParent(); |
| 1358 | + else if (auto *I = dyn_cast<Instruction>(V)) |
| 1359 | + F = I->getFunction(); |
| 1360 | + |
| 1361 | + if (F) { |
| 1362 | + auto *UA = |
| 1363 | + A.getInfoCache() |
| 1364 | + .getAnalysisResultForFunction<UniformityInfoAnalysis>(*F); |
| 1365 | + return UA && UA->isUniform(V); |
| 1366 | + } |
| 1367 | + |
| 1368 | + // What else can it be here? |
| 1369 | + return false; |
| 1370 | + }; |
| 1371 | + |
| 1372 | + bool UsedAssumedInformation = true; |
| 1373 | + if (!A.checkForAllCallSites(isUniform, *this, /*RequireAllCallSites=*/true, |
| 1374 | + UsedAssumedInformation)) |
| 1375 | + return indicatePessimisticFixpoint(); |
| 1376 | + |
| 1377 | + if (!UsedAssumedInformation) |
| 1378 | + return indicateOptimisticFixpoint(); |
| 1379 | + |
| 1380 | + return ChangeStatus::UNCHANGED; |
| 1381 | + } |
| 1382 | + |
| 1383 | + ChangeStatus manifest(Attributor &A) override { |
| 1384 | + return A.manifestAttrs( |
| 1385 | + getIRPosition(), |
| 1386 | + {Attribute::get(getAnchorValue().getContext(), Attribute::InReg)}); |
| 1387 | + } |
| 1388 | +}; |
| 1389 | + |
| 1390 | +AAAMDGPUUniform &AAAMDGPUUniform::createForPosition(const IRPosition &IRP, |
| 1391 | + Attributor &A) { |
| 1392 | + switch (IRP.getPositionKind()) { |
| 1393 | + case IRPosition::IRP_ARGUMENT: |
| 1394 | + return *new (A.Allocator) AAAMDGPUUniformArgument(IRP, A); |
| 1395 | + // TODO: Since inreg is also allowed for return value, maybe we need to add |
| 1396 | + // AAAMDGPUUniformCallSiteReturned? |
| 1397 | + default: |
| 1398 | + llvm_unreachable("not a valid position for AAAMDGPUUniform"); |
| 1399 | + } |
| 1400 | +} |
| 1401 | + |
1302 | 1402 | /// Performs the final check and updates the 'amdgpu-waves-per-eu' attribute
|
1303 | 1403 | /// based on the finalized 'amdgpu-flat-work-group-size' attribute.
|
1304 | 1404 | /// Both attributes start with narrow ranges that expand during iteration.
|
@@ -1385,7 +1485,7 @@ static bool runImpl(Module &M, AnalysisGetter &AG, TargetMachine &TM,
|
1385 | 1485 | &AAAMDMaxNumWorkgroups::ID, &AAAMDWavesPerEU::ID, &AAAMDGPUNoAGPR::ID,
|
1386 | 1486 | &AACallEdges::ID, &AAPointerInfo::ID, &AAPotentialConstantValues::ID,
|
1387 | 1487 | &AAUnderlyingObjects::ID, &AAAddressSpace::ID, &AAIndirectCallInfo::ID,
|
1388 |
| - &AAInstanceInfo::ID}); |
| 1488 | + &AAInstanceInfo::ID, &AAAMDGPUUniform::ID}); |
1389 | 1489 |
|
1390 | 1490 | AttributorConfig AC(CGUpdater);
|
1391 | 1491 | AC.IsClosedWorldModule = Options.IsClosedWorld;
|
@@ -1438,6 +1538,11 @@ static bool runImpl(Module &M, AnalysisGetter &AG, TargetMachine &TM,
|
1438 | 1538 | IRPosition::value(*CmpX->getPointerOperand()));
|
1439 | 1539 | }
|
1440 | 1540 | }
|
| 1541 | + |
| 1542 | + if (!AMDGPU::isEntryFunctionCC(F->getCallingConv())) { |
| 1543 | + for (auto &Arg : F->args()) |
| 1544 | + A.getOrCreateAAFor<AAAMDGPUUniform>(IRPosition::argument(Arg)); |
| 1545 | + } |
1441 | 1546 | }
|
1442 | 1547 |
|
1443 | 1548 | bool Changed = A.run() == ChangeStatus::CHANGED;
|
@@ -1470,6 +1575,7 @@ class AMDGPUAttributorLegacy : public ModulePass {
|
1470 | 1575 |
|
1471 | 1576 | void getAnalysisUsage(AnalysisUsage &AU) const override {
|
1472 | 1577 | AU.addRequired<CycleInfoWrapperPass>();
|
| 1578 | + AU.addRequired<UniformityInfoWrapperPass>(); |
1473 | 1579 | }
|
1474 | 1580 |
|
1475 | 1581 | StringRef getPassName() const override { return "AMDGPU Attributor"; }
|
|
0 commit comments