[LLVMdev] Finding all values derived from a function argument

Stephan Reiter stephan.reiter at gmail.com
Thu Sep 23 12:20:39 PDT 2010


Hello!

I am trying to retrieve all instructions from a function's body that
are dependent on a specific argument. The strategy I am currently
using for that is to follow all uses of the argument and record them.
Also, whenever I encounter a store of a dependent value, I try to find
loads in the function that are dependent on that store and resume
use-tracking from there. For this purpose I am using the
MemoryDependenceAnalysis pass, but to be honest, I think I am not
using it correctly or not in the most efficient way.

Is such functionality - finding dependent instructions - present in
LLVM? If not, is there a more efficient way to determine dependent
instructions than like in the code below? In particular, I'm wondering
if it is possible to find all loads that depend on a particular store
more efficiently?

Thank you,
Stephan

    llvm::DenseSet<llvm::Instruction *> findDependents(llvm::Argument
*arg, llvm::Function *func)
    {
      std::vector<llvm::Instruction *> workList;
      for(llvm::Argument::use_iterator I = arg->use_begin(), E =
arg->use_end(); I != E; ++I)
      {
        if(llvm::Instruction *user = llvm::dyn_cast<llvm::Instruction>(*I))
          workList.push_back(user);
      }

      llvm::FunctionPassManager fpm(func->getParent());
      llvm::MemoryDependenceAnalysis *mda = new
llvm::MemoryDependenceAnalysis();
      fpm.add(mda);
      fpm.run(*func);

      // find all loads in the current function
      std::list<llvm::LoadInst *> loads;
      for(llvm::Function::iterator I = func->begin(), E = func->end();
I != E; ++I)
      {
        for(llvm::BasicBlock::iterator II = I->begin(), EE = I->end();
II != EE; ++II)
        {
          if(llvm::LoadInst *load = llvm::dyn_cast<llvm::LoadInst>(II))
            loads.push_back(load);
        }
      }

      llvm::DenseSet<llvm::Instruction *> deps;
      for(;;)
      {
        llvm::DenseSet<llvm::Instruction *> stores;
        while(!workList.empty())
        {
          llvm::Instruction *I = workList.back();
          workList.pop_back();

          if(deps.count(I) != 0)
            continue;

          deps.insert(I);

          if(llvm::StoreInst *store = llvm::dyn_cast<llvm::StoreInst>(I))
            stores.insert(I);

          for(llvm::Value::use_iterator II = I->use_begin(), EE =
I->use_end(); II != EE; ++II)
          {
            if(llvm::Instruction *user = llvm::dyn_cast<llvm::Instruction>(*II))
              workList.push_back(user);
          }
        }

        if(stores.size() > 0)
        {
          // find loads that depend on our stores, TODO: this seems fishy!
          for(std::list<llvm::LoadInst *>::iterator I = loads.begin(),
E = loads.end(); I != E; )
          {
            bool pick = false;
#if 1
            llvm::SmallVector<llvm::NonLocalDepResult, 16> results;
            mda->getNonLocalPointerDependency((*I)->getPointerOperand(),
true, (*I)->getParent(), results);
            for(llvm::SmallVector<llvm::NonLocalDepResult,
16>::iterator II = results.begin(), EE = results.end(); !pick && II !=
EE; ++II)
            {
              const llvm::MemDepResult &result = II->getResult();
              if(llvm::Instruction *dep = result.getInst())
              {
                if(llvm::StoreInst *store =
llvm::dyn_cast<llvm::StoreInst>(dep))
                  pick |= (stores.count(store) != 0);
              }
            }
#else
            llvm::MemDepResult result = mda->getDependency(*I);
            if(llvm::Instruction *dep = result.getInst())
            {
              if(llvm::StoreInst *store = llvm::dyn_cast<llvm::StoreInst>(dep))
                pick = (stores.count(store) != 0);
            }
#endif
            if(pick)
            {
              workList.push_back(*I);
              I = loads.erase(I);
            }
            else
              ++I;
          }

          stores.clear();
        }
        else
          break;
      }
      return deps;
    }



More information about the llvm-dev mailing list