在循环外部使用的LLVM LoopPass值

在循环外部使用的LLVM LoopPass值,llvm,llvm-ir,Llvm,Llvm Ir,我正在编写一个LLVM循环过程,其中我需要知道哪些值 在循环外部使用。为此,我有以下代码: virtual bool runOnLoop(Loop *loop, LPPassManager &LPM) { for (auto it = loop->block_begin(); it != loop->block_end(); it++) { for (auto inst = (*it)->begin(); inst != (*it)-&g

我正在编写一个LLVM循环过程,其中我需要知道哪些值 在循环外部使用。为此,我有以下代码:

virtual bool runOnLoop(Loop *loop, LPPassManager &LPM)
{
    for (auto it = loop->block_begin(); it != loop->block_end(); it++)
    {
        for (auto inst = (*it)->begin(); inst != (*it)->end(); inst++)
        {
            if (Is_Used_Outside_This_loop(loop,(Instruction *) inst))
            {
                errs() << inst->getName().str();
                errs() << " is used outside the loop\n";
            }
        }
    }
    // ...
}
以下*.ll代码显示
%tmp5
使用了两次 在循环的基本块内。当我仔细搜索API时, 我找不到类似Value::numUsesInBasicBlock(…)的内容


显然,一定有办法做到这一点,对吗?谢谢

下面是我如何解决它的,尽管它看起来过于复杂:

virtual bool runOnLoop(Loop *loop, LPPassManager &LPM)
{
    for (auto it = loop->block_begin(); it != loop->block_end(); it++)
    {
        for (auto inst = (*it)->begin(); inst != (*it)->end(); inst++)
        {
            int n=0;
            for (auto use = inst->use_begin(); use != inst->use_end(); use++)
            {
                Instruction *i = (Instruction *) use->getUser();
                if (BasicBlockBelongsToLoop(i->getParent(),loop))
                {
                    n++;
                }
            }
            assert(n <= inst->getNumUses());
            if (n < inst->getNumUses())
            {
                errs() << inst->getName().str();
                errs() << " is used outside the loop\n";
            }
        }
    }
    // ...

问题是你的退出条件。您请求使用,但随后将其与使用该值的块数进行比较

因此,如果该值在同一个基本块中使用了两次,则使用次数为2,并且使用该值的基本块的
n
计数器只增加一次,因此
n
numes
不匹配

也许做你想做的事情更简洁的方法是:

void FindUsesNotIn(
  llvm::SmallPtrSetImpl<llvm::BasicBlock *> &Blocks,
  llvm::SmallPtrSetImpl<llvm::Value *> &OutUses) {
  for(const auto &b : Blocks)
    for(auto &i : *b)
      for(const auto &u : i.users()) {
        auto *userInst = llvm::dyn_cast<llvm::Instruction>(u);

        if(userInst && !Blocks.count(userInst->getParent())) {
          OutUses.insert(&i);
          break;
        }
      }
}

你能把这个通行证操作的整个LLVM IR都贴出来吗?另外,退出函数时的
n
numeses
的值是什么
是否在该循环()之外使用?
virtual bool runOnLoop(Loop *loop, LPPassManager &LPM)
{
    for (auto it = loop->block_begin(); it != loop->block_end(); it++)
    {
        for (auto inst = (*it)->begin(); inst != (*it)->end(); inst++)
        {
            int n=0;
            for (auto use = inst->use_begin(); use != inst->use_end(); use++)
            {
                Instruction *i = (Instruction *) use->getUser();
                if (BasicBlockBelongsToLoop(i->getParent(),loop))
                {
                    n++;
                }
            }
            assert(n <= inst->getNumUses());
            if (n < inst->getNumUses())
            {
                errs() << inst->getName().str();
                errs() << " is used outside the loop\n";
            }
        }
    }
    // ...
bool BasicBlockBelongsToLoop(BasicBlock *BB, Loop *loop)
{
    for (auto it = loop->block_begin(); it != loop->block_end(); it++)
    {
        if (BB == (*it))
        {
            return true;
        }
    }
    return false;
}
void FindUsesNotIn(
  llvm::SmallPtrSetImpl<llvm::BasicBlock *> &Blocks,
  llvm::SmallPtrSetImpl<llvm::Value *> &OutUses) {
  for(const auto &b : Blocks)
    for(auto &i : *b)
      for(const auto &u : i.users()) {
        auto *userInst = llvm::dyn_cast<llvm::Instruction>(u);

        if(userInst && !Blocks.count(userInst->getParent())) {
          OutUses.insert(&i);
          break;
        }
      }
}
virtual bool runOnLoop(llvm::Loop *loop, llvm::LPPassManager &LPM) {
  llvm::SmallPtrSet<llvm::BasicBlock*, 10> loopBlocks(loop->block_begin(), loop->block_end());
  llvm::SmallPtrSet<llvm::Value *, 10> outs;

  FindUsesNotIn(loopBlocks, outs);

  for(const auto *e : outs)
    llvm::dbgs() << *e << '\n';

  return false;
}