// deleteValue method - This method is used to remove a pointer value from the
// AliasSetTracker entirely.  It should be used when an instruction is deleted
// from the program to update the AST.  If you don't use this, you would have
// dangling pointers to deleted instructions.
//
void AliasSetTracker::deleteValue(Value *PtrVal) {
  // Notify the alias analysis implementation that this value is gone.
  AA.deleteValue(PtrVal);

  // If this is a call instruction, remove the callsite from the appropriate
  // AliasSet.
  CallSite CS = CallSite::get(PtrVal);
  if (CS.getInstruction()) {
    Function *F = CS.getCalledFunction();
    if (!F || !AA.doesNotAccessMemory(F)) {
      if (AliasSet *AS = findAliasSetForCallSite(CS))
        AS->removeCallSite(CS);
    }
  }

  // First, look up the PointerRec for this pointer.
  hash_map<Value*, AliasSet::PointerRec>::iterator I = PointerMap.find(PtrVal);
  if (I == PointerMap.end()) return;  // Noop

  // If we found one, remove the pointer from the alias set it is in.
  AliasSet::HashNodePair &PtrValEnt = *I;
  AliasSet *AS = PtrValEnt.second.getAliasSet(*this);

  // Unlink from the list of values...
  PtrValEnt.second.removeFromList();
  // Stop using the alias set
  AS->dropRef(*this);
  PointerMap.erase(I);
}
// deleteValue method - This method is used to remove a pointer value from the
// AliasSetTracker entirely.  It should be used when an instruction is deleted
// from the program to update the AST.  If you don't use this, you would have
// dangling pointers to deleted instructions.
//
void AliasSetTracker::deleteValue(Value *PtrVal) {
  // Notify the alias analysis implementation that this value is gone.
  AA.deleteValue(PtrVal);

  // If this is a call instruction, remove the callsite from the appropriate
  // AliasSet (if present).
  if (Instruction *Inst = dyn_cast<Instruction>(PtrVal)) {
    if (Inst->mayReadOrWriteMemory()) {
      // Scan all the alias sets to see if this call site is contained.
      for (iterator I = begin(), E = end(); I != E;) {
        iterator Cur = I++;
        if (!Cur->Forward)
          Cur->removeUnknownInst(*this, Inst);
      }
    }
  }

  // First, look up the PointerRec for this pointer.
  PointerMapType::iterator I = PointerMap.find_as(PtrVal);
  if (I == PointerMap.end()) return;  // Noop

  // If we found one, remove the pointer from the alias set it is in.
  AliasSet::PointerRec *PtrValEnt = I->second;
  AliasSet *AS = PtrValEnt->getAliasSet(*this);

  // Unlink and delete from the list of values.
  PtrValEnt->eraseFromList();
  
  // Stop using the alias set.
  AS->dropRef(*this);
  
  PointerMap.erase(I);
}
/// remove - Remove the specified (potentially non-empty) alias set from the
/// tracker.
void AliasSetTracker::remove(AliasSet &AS) {
  // Drop all call sites.
  if (!AS.UnknownInsts.empty())
    AS.dropRef(*this);
  AS.UnknownInsts.clear();
  
  // Clear the alias set.
  unsigned NumRefs = 0;
  while (!AS.empty()) {
    AliasSet::PointerRec *P = AS.PtrList;

    Value *ValToRemove = P->getValue();
    
    // Unlink and delete entry from the list of values.
    P->eraseFromList();
    
    // Remember how many references need to be dropped.
    ++NumRefs;

    // Finally, remove the entry.
    PointerMap.erase(ValToRemove);
  }
  
  // Stop using the alias set, removing it.
  AS.RefCount -= NumRefs;
  if (AS.RefCount == 0)
    AS.removeFromTracker(*this);
}
// deleteValue method - This method is used to remove a pointer value from the
// AliasSetTracker entirely.  It should be used when an instruction is deleted
// from the program to update the AST.  If you don't use this, you would have
// dangling pointers to deleted instructions.
//
void AliasSetTracker::deleteValue(Value *PtrVal) {
  // Notify the alias analysis implementation that this value is gone.
  AA.deleteValue(PtrVal);

  // If this is a call instruction, remove the callsite from the appropriate
  // AliasSet (if present).
  if (CallSite CS = PtrVal) {
    if (!AA.doesNotAccessMemory(CS)) {
      // Scan all the alias sets to see if this call site is contained.
      for (iterator I = begin(), E = end(); I != E; ++I) {
        if (I->Forward) continue;
        
        I->removeCallSite(CS);
      }
    }
  }

  // First, look up the PointerRec for this pointer.
  PointerMapType::iterator I = PointerMap.find(PtrVal);
  if (I == PointerMap.end()) return;  // Noop

  // If we found one, remove the pointer from the alias set it is in.
  AliasSet::PointerRec *PtrValEnt = I->second;
  AliasSet *AS = PtrValEnt->getAliasSet(*this);

  // Unlink and delete from the list of values.
  PtrValEnt->eraseFromList();
  
  // Stop using the alias set.
  AS->dropRef(*this);
  
  PointerMap.erase(I);
}
Example #5
0
// deleteValue method - This method is used to remove a pointer value from the
// AliasSetTracker entirely.  It should be used when an instruction is deleted
// from the program to update the AST.  If you don't use this, you would have
// dangling pointers to deleted instructions.
//
void AliasSetTracker::deleteValue(Value *PtrVal) {
  // Notify the alias analysis implementation that this value is gone.
  AA.deleteValue(PtrVal);

  // If this is a call instruction, remove the callsite from the appropriate
  // AliasSet.
  CallSite CS = CallSite::get(PtrVal);
  if (CS.getInstruction())
    if (!AA.doesNotAccessMemory(CS))
      if (AliasSet *AS = findAliasSetForCallSite(CS))
        AS->removeCallSite(CS);

  // First, look up the PointerRec for this pointer.
  PointerMapType::iterator I = PointerMap.find(PtrVal);
  if (I == PointerMap.end()) return;  // Noop

  // If we found one, remove the pointer from the alias set it is in.
  AliasSet::PointerRec *PtrValEnt = I->second;
  AliasSet *AS = PtrValEnt->getAliasSet(*this);

  // Unlink and delete from the list of values.
  PtrValEnt->eraseFromList();
  
  // Stop using the alias set.
  AS->dropRef(*this);
  
  PointerMap.erase(I);
}
/// mergeSetIn - Merge the specified alias set into this alias set.
///
void AliasSet::mergeSetIn(AliasSet &AS, AliasSetTracker &AST) {
  assert(!AS.Forward && "Alias set is already forwarding!");
  assert(!Forward && "This set is a forwarding set!!");

  // Update the alias and access types of this set...
  AccessTy |= AS.AccessTy;
  AliasTy  |= AS.AliasTy;
  Volatile |= AS.Volatile;

  if (AliasTy == MustAlias) {
    // Check that these two merged sets really are must aliases.  Since both
    // used to be must-alias sets, we can just check any pointer from each set
    // for aliasing.
    AliasAnalysis &AA = AST.getAliasAnalysis();
    PointerRec *L = getSomePointer();
    PointerRec *R = AS.getSomePointer();

    // If the pointers are not a must-alias pair, this set becomes a may alias.
    if (AA.alias(AliasAnalysis::Location(L->getValue(),
                                         L->getSize(),
                                         L->getAAInfo()),
                 AliasAnalysis::Location(R->getValue(),
                                         R->getSize(),
                                         R->getAAInfo()))
        != AliasAnalysis::MustAlias)
      AliasTy = MayAlias;
  }

  bool ASHadUnknownInsts = !AS.UnknownInsts.empty();
  if (UnknownInsts.empty()) {            // Merge call sites...
    if (ASHadUnknownInsts) {
      std::swap(UnknownInsts, AS.UnknownInsts);
      addRef();
    }
  } else if (ASHadUnknownInsts) {
    UnknownInsts.insert(UnknownInsts.end(), AS.UnknownInsts.begin(), AS.UnknownInsts.end());
    AS.UnknownInsts.clear();
  }

  AS.Forward = this;  // Forward across AS now...
  addRef();           // AS is now pointing to us...

  // Merge the list of constituent pointers...
  if (AS.PtrList) {
    *PtrListEnd = AS.PtrList;
    AS.PtrList->setPrevInList(PtrListEnd);
    PtrListEnd = AS.PtrListEnd;

    AS.PtrList = nullptr;
    AS.PtrListEnd = &AS.PtrList;
    assert(*AS.PtrListEnd == nullptr && "End of list is not null?");
  }
  if (ASHadUnknownInsts)
    AS.dropRef(AST);
}
Example #7
0
// deleteValue method - This method is used to remove a pointer value from the
// AliasSetTracker entirely.  It should be used when an instruction is deleted
// from the program to update the AST.  If you don't use this, you would have
// dangling pointers to deleted instructions.
//
void AliasSetTracker::deleteValue(Value *PtrVal) {
  // First, look up the PointerRec for this pointer.
  PointerMapType::iterator I = PointerMap.find_as(PtrVal);
  if (I == PointerMap.end()) return;  // Noop

  // If we found one, remove the pointer from the alias set it is in.
  AliasSet::PointerRec *PtrValEnt = I->second;
  AliasSet *AS = PtrValEnt->getAliasSet(*this);

  // Unlink and delete from the list of values.
  PtrValEnt->eraseFromList();

  if (AS->Alias == AliasSet::SetMayAlias) {
    AS->SetSize--;
    TotalMayAliasSetSize--;
  }

  // Stop using the alias set.
  AS->dropRef(*this);

  PointerMap.erase(I);
}
Example #8
0
AliasSet &AliasSetTracker::mergeAllAliasSets() {
  assert(!AliasAnyAS && (TotalMayAliasSetSize > SaturationThreshold) &&
         "Full merge should happen once, when the saturation threshold is "
         "reached");

  // Collect all alias sets, so that we can drop references with impunity
  // without worrying about iterator invalidation.
  std::vector<AliasSet *> ASVector;
  ASVector.reserve(SaturationThreshold);
  for (iterator I = begin(), E = end(); I != E; I++)
    ASVector.push_back(&*I);

  // Copy all instructions and pointers into a new set, and forward all other
  // sets to it.
  AliasSets.push_back(new AliasSet());
  AliasAnyAS = &AliasSets.back();
  AliasAnyAS->Alias = AliasSet::SetMayAlias;
  AliasAnyAS->Access = AliasSet::ModRefAccess;
  AliasAnyAS->AliasAny = true;

  for (auto Cur : ASVector) {
    // If Cur was already forwarding, just forward to the new AS instead.
    AliasSet *FwdTo = Cur->Forward;
    if (FwdTo) {
      Cur->Forward = AliasAnyAS;
      AliasAnyAS->addRef();
      FwdTo->dropRef(*this);
      continue;
    }

    // Otherwise, perform the actual merge.
    AliasAnyAS->mergeSetIn(*Cur, *this);
  }

  return *AliasAnyAS;
}