diff options
| author | Johannes Doerfert <jdoerfert@anl.gov> | 2019-08-26 17:48:05 +0000 | 
|---|---|---|
| committer | Johannes Doerfert <jdoerfert@anl.gov> | 2019-08-26 17:48:05 +0000 | 
| commit | 19b0043641734c44e8a993250d31735f2c59d7b1 (patch) | |
| tree | f7302fae34a55783ac909cfae2057f5043b22937 /llvm/lib/Transforms | |
| parent | 51029e5c153bd33efa015e2ec35b60247d046ce4 (diff) | |
| download | bcm5719-llvm-19b0043641734c44e8a993250d31735f2c59d7b1.tar.gz bcm5719-llvm-19b0043641734c44e8a993250d31735f2c59d7b1.zip | |
[Attributor] Allow explicit dependence tracking
By default, the Attributor tracks potential dependences between abstract
attributes based on the issued Attributor::getAAFor queries. This
simplifies the development of new abstract attributes but it can also
lead to spurious dependences that might increase compile time and make
internalization harder (D63312). With this patch, abstract attributes
can opt-out of implicit dependence tracking and instead register
dependences explicitly. It is up to the implementation to make sure all
existing dependences are registered.
Differential Revision: https://reviews.llvm.org/D63314
llvm-svn: 369935
Diffstat (limited to 'llvm/lib/Transforms')
| -rw-r--r-- | llvm/lib/Transforms/IPO/Attributor.cpp | 58 | 
1 files changed, 44 insertions, 14 deletions
| diff --git a/llvm/lib/Transforms/IPO/Attributor.cpp b/llvm/lib/Transforms/IPO/Attributor.cpp index 029017a5690..a2ea0068bc0 100644 --- a/llvm/lib/Transforms/IPO/Attributor.cpp +++ b/llvm/lib/Transforms/IPO/Attributor.cpp @@ -146,7 +146,9 @@ bool genericValueTraversal(    const AAIsDead *LivenessAA = nullptr;    if (IRP.getAnchorScope())      LivenessAA = &A.getAAFor<AAIsDead>( -        QueryingAA, IRPosition::function(*IRP.getAnchorScope())); +        QueryingAA, IRPosition::function(*IRP.getAnchorScope()), +        /* TrackDependence */ false); +  bool AnyDead = false;    // TODO: Use Positions here to allow context sensitivity in VisitValueCB    SmallPtrSet<Value *, 16> Visited; @@ -199,8 +201,11 @@ bool genericValueTraversal(               "Expected liveness in the presence of instructions!");        for (unsigned u = 0, e = PHI->getNumIncomingValues(); u < e; u++) {          const BasicBlock *IncomingBB = PHI->getIncomingBlock(u); -        if (!LivenessAA->isAssumedDead(IncomingBB->getTerminator())) -          Worklist.push_back(PHI->getIncomingValue(u)); +        if (LivenessAA->isAssumedDead(IncomingBB->getTerminator())) { +          AnyDead =true; +          continue; +        } +        Worklist.push_back(PHI->getIncomingValue(u));        }        continue;      } @@ -210,6 +215,10 @@ bool genericValueTraversal(        return false;    } while (!Worklist.empty()); +  // If we actually used liveness information so we have to record a dependence. +  if (AnyDead) +    A.recordDependence(*LivenessAA, QueryingAA); +    // All values have been visited.    return true;  } @@ -2282,7 +2291,8 @@ bool Attributor::isAssumedDead(const AbstractAttribute &AA,    if (!LivenessAA)      LivenessAA = -        &getAAFor<AAIsDead>(AA, IRPosition::function(*CtxI->getFunction())); +        &getAAFor<AAIsDead>(AA, IRPosition::function(*CtxI->getFunction()), +                            /* TrackDependence */ false);    // Don't check liveness for AAIsDead.    if (&AA == LivenessAA) @@ -2291,8 +2301,9 @@ bool Attributor::isAssumedDead(const AbstractAttribute &AA,    if (!LivenessAA->isAssumedDead(CtxI))      return false; -  // TODO: Do not track dependences automatically but add it here as only a -  //       "is-assumed-dead" result causes a dependence. +  // We actually used liveness information so we have to record a dependence. +  recordDependence(*LivenessAA, AA); +    return true;  } @@ -2323,12 +2334,16 @@ bool Attributor::checkForAllCallSites(const function_ref<bool(CallSite)> &Pred,      Function *Caller = I->getFunction(); -    const auto &LivenessAA = -        getAAFor<AAIsDead>(QueryingAA, IRPosition::function(*Caller)); +    const auto &LivenessAA = getAAFor<AAIsDead>( +        QueryingAA, IRPosition::function(*Caller), /* TrackDependence */ false);      // Skip dead calls. -    if (LivenessAA.isAssumedDead(I)) +    if (LivenessAA.isAssumedDead(I)) { +      // We actually used liveness information so we have to record a +      // dependence. +      recordDependence(LivenessAA, QueryingAA);        continue; +    }      CallSite CS(U.getUser());      if (!CS || !CS.isCallee(&U) || !CS.getCaller()->hasExactDefinition()) { @@ -2405,21 +2420,29 @@ bool Attributor::checkForAllInstructions(      return false;    const IRPosition &QueryIRP = IRPosition::function_scope(IRP); -  const auto &LivenessAA = getAAFor<AAIsDead>(QueryingAA, QueryIRP); +  const auto &LivenessAA = +      getAAFor<AAIsDead>(QueryingAA, QueryIRP, /* TrackDependence */ false); +  bool AnyDead = false;    auto &OpcodeInstMap =        InfoCache.getOpcodeInstMapForFunction(*AssociatedFunction);    for (unsigned Opcode : Opcodes) {      for (Instruction *I : OpcodeInstMap[Opcode]) {        // Skip dead instructions. -      if (LivenessAA.isAssumedDead(I)) +      if (LivenessAA.isAssumedDead(I)) { +        AnyDead = true;          continue; +      }        if (!Pred(*I))          return false;      }    } +  // If we actually used liveness information so we have to record a dependence. +  if (AnyDead) +    recordDependence(LivenessAA, QueryingAA); +    return true;  } @@ -2432,19 +2455,26 @@ bool Attributor::checkForAllReadWriteInstructions(    if (!AssociatedFunction)      return false; -  const auto &LivenessAA = -      getAAFor<AAIsDead>(QueryingAA, QueryingAA.getIRPosition()); +  const auto &LivenessAA = getAAFor<AAIsDead>( +      QueryingAA, QueryingAA.getIRPosition(), /* TrackDependence */ false); +  bool AnyDead = false;    for (Instruction *I :         InfoCache.getReadOrWriteInstsForFunction(*AssociatedFunction)) {      // Skip dead instructions. -    if (LivenessAA.isAssumedDead(I)) +    if (LivenessAA.isAssumedDead(I)) { +      AnyDead = true;        continue; +    }      if (!Pred(*I))        return false;    } +  // If we actually used liveness information so we have to record a dependence. +  if (AnyDead) +    recordDependence(LivenessAA, QueryingAA); +    return true;  } | 

