前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >LLVM(3)编写Pass

LLVM(3)编写Pass

作者头像
mingjie
发布2023-10-13 10:29:01
2450
发布2023-10-13 10:29:01
举报

总结

LLVM Pass简单总结:对IR进行遍历、优化的逻辑,例如:

代码语言:javascript
复制
opt --help
	...
	...
	Optimizations available (use '-passes=' for the new pass manager)
		...
		...
        --loop-deletion         - Delete dead loops
        --memcpyopt             - MemCpy Optimization
        --print-callgraph       - Print a call graph
        ...
        ...

opt提供了很多pass,例如检测代码中的死循环、对代码中的memcpy优化、遍历全部函数分析调用关系等等。

上述都是pass可实现的功能,llvm工程中给出了一个实例:

hello pass实例

LLVM version 16.0.6

库中位置:llvm/lib/Transforms/Hello/Hello.cpp

代码语言:javascript
复制
//===- Hello.cpp - Example code from "Writing an LLVM Pass" ---------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements two versions of the LLVM "Hello World" pass described
// in docs/WritingAnLLVMPass.html
//
//===----------------------------------------------------------------------===//

#include "llvm/ADT/Statistic.h"
#include "llvm/IR/Function.h"
#include "llvm/Pass.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;

#define DEBUG_TYPE "hello"

STATISTIC(HelloCounter, "Counts number of functions greeted");

namespace {
  // Hello - The first implementation, without getAnalysisUsage.
  struct Hello : public FunctionPass {
    static char ID; // Pass identification, replacement for typeid
    Hello() : FunctionPass(ID) {}

    bool runOnFunction(Function &F) override {
      ++HelloCounter;
      errs() << "Hello: ";
      errs().write_escaped(F.getName()) << '\n';
      return false;
    }
  };
}

char Hello::ID = 0;
static RegisterPass<Hello> X("hello", "Hello World Pass");

namespace {
  // Hello2 - The second implementation with getAnalysisUsage implemented.
  struct Hello2 : public FunctionPass {
    static char ID; // Pass identification, replacement for typeid
    Hello2() : FunctionPass(ID) {}

    bool runOnFunction(Function &F) override {
      ++HelloCounter;
      errs() << "Hello: ";
      errs().write_escaped(F.getName()) << '\n';
      return false;
    }

    // We don't modify the program, so we preserve all analyses.
    void getAnalysisUsage(AnalysisUsage &AU) const override {
      AU.setPreservesAll();
    }
  };
}

char Hello2::ID = 0;
static RegisterPass<Hello2>
Y("hello2", "Hello World Pass (with getAnalysisUsage implemented)");

这个pass会跟着工程编译,无需自己编译了。

生成的so位置:pathto/llvm-project/build/lib/LLVMHello.so

如何使用pass?

pass需要分析IR,先生成一个IR:

t3.cpp

代码语言:javascript
复制
int g_var = 0;

int factorial(int val);

int factorial(int val)
{
	g_var = 1;
	if (val <= 2)
		return 1;

	return factorial(val - 1) + factorial(val - 2);
}

int factorial_iter(int val)
{
	int temp = 1;
	for (int i = 2; i <= val; ++i)
		temp *= i;
	return temp;
}

int main(int argc, char **argv)
{
	return factorial(2) * 7 == 42;
}

生成IR

$ clang -O0 -emit-llvm t3.cpp -c -o t3.bc

用pass分析t3.bc

代码语言:javascript
复制
$ opt  -load pathto/llvm-project/build/lib/LLVMHello.so -enable-new-pm=0 -hello t3.bc
Hello: _Z9factoriali
Hello: _Z14factorial_iteri
Hello: main
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-07-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 总结
  • hello pass实例
  • 如何使用pass?
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档