【工作日志】1月6日——LLVM

发布时间:2024年01月06日

继续学习LLVM笔记。

SSA

LLVM的新版本好像将phi替换成了select,有必要研究一下二者的区别。

Transforms

ADCE

查询一下control dependence 和Terminator分别是什么意思。
DenseMap
SmallPtrSet,定义该类使用了模板,其中第一个参数表示Set中的元素类型,第二个参数表示Set的大小,使用下述代码创建了一个类型为BasicBlock,大小为16的集合:

/// Set of blocks with not known to have live terminators.
  SmallSetVector<BasicBlock *, 16> BlocksWithDeadTerminators;

执行removeDeadInstructions()时,我注意到返回值是ADCEChanged,该struct定义在同一个文件中,定义代码如下:

struct ADCEChanged {
  bool ChangedAnything = false;
  bool ChangedNonDebugInstr = false;
  bool ChangedControlFlow = false;
};

其中ChangedNonDebugInstr比较费解,带入到源代码中(下面的是简化版):

if (auto *DII = dyn_cast<DbgInfoIntrinsic>(&I)) {
      
    } else {
      Changed.ChangedNonDebugInstr = true;
    }

其实就是判断是否有非DebugInfoInstrinsic指令的修改,也即是否有用户编写的指令修改,如果LLVM生成的Debug信息造成的死代码消除,说明用户编写的源程序不存在分析出的死代码。
后续使用也可以看到

if (!Changed.ChangedNonDebugInstr) {
      // Only removing debug instructions does not affect MemorySSA.
      //
      // Therefore we preserve MemorySSA when only removing debug instructions
      // since otherwise later passes may behave differently which then makes
      // the presence of debug info affect code generation.
      PA.preserve<MemorySSAAnalysis>();
    }

目前有一个疑问,为什么两个判断结构的封装是嵌套的,也即是否存在修改了ControlFlow但没有修改NonDebugInstr。这样的话判断结构就不存在了:

PreservedAnalyses PA;
  if (!Changed.ChangedControlFlow) {
    PA.preserveSet<CFGAnalyses>();
    if (!Changed.ChangedNonDebugInstr) {
      // Only removing debug instructions does not affect MemorySSA.
      //
      // Therefore we preserve MemorySSA when only removing debug instructions
      // since otherwise later passes may behave differently which then makes
      // the presence of debug info affect code generation.
      PA.preserve<MemorySSAAnalysis>();
    }
  }
  PA.preserve<DominatorTreeAnalysis>();
  PA.preserve<PostDominatorTreeAnalysis>();
 
  return PA;

留待以后思考吧。

static bool isUnconditionalBranch(Instruction *Term) {
  auto *BR = dyn_cast<BranchInst>(Term);
  return BR && BR->isUnconditional();
}

这个函数也有意思,LLVM把dyn_cast用活了,奇技淫巧get。
LLVM在上述程序中为什么不适用isa<BranchInst>(Term),想必是因为该函数不仅要求是BranchInst还要求是UnConditionalBranch。
为什么UnconditionalBranch在该例子中是特殊的,在下述代码中也有所透露:

	// Mark unconditional branches at the end of live
  // blocks as live since there is no work to do for them later
  if (BBInfo.UnconditionalBranch)
    markLive(BBInfo.Terminator);
文章来源:https://blog.csdn.net/weixin_45207619/article/details/135426448
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。