一、理论基础
别名分析是许多编译优化得以顺利进行的一个前提,也是分析程序特征的一个基础手段。通常而言,别名分析有以下几类:
(1)按是否与控制流相关可分为:flow-sensitive vs flow-insensitive
(2)按是否与上下文相关可分为:context-sensitive vs context-insensitive
(3)按是否与特定领域相关可分为:field-sensitive vs field-insensitive
(4)按实现方式可分为:unification-based vs subset-based
在进行别名分析时,区分别名类型:Must,May,No是十分重要的。由于判定任意变量在运行时是否真的相关的问题,是一个不可判定问题,它等价于图灵机停机问题,所以编译人员无论是对程序进行静态还是动态别名分析,总是存在无法确定的情况。当我们肯定两个变量或者指针的别名是一定存在的则别名类型为Must,若肯定他们是不存在的则别名类型是No,否则只能是May。对May类型的别名关系,我们必须承认它但不能依靠它;而对Must和No类型的别名关系,我们可以充分信任。
关于别名关系的详细理论和更深层次的讨论可以参考Muchnick的《高级编译器设计与实现》和Andersen的博士论文《Program Analysis and Specialization for the C Programming Language》。
二、LLVM接口类 AliasAnalysis
LLVM针对别名关系提出了统一的抽象类 AliasAnalysis,该类定义了各种别名分析需要实现的接口。该类定义了表示别名关系的公共枚举类型: AliasResult and ModRefResult,其定义如下:
enum AliasResult { NoAlias = 0, MayAlias = 1, MustAlias = 2 };
enum ModRefResult { NoModRef = 0, Ref = 1, Mod = 2, ModRef = 3 };
其中定义的接口有:
(1) virtual AliasResult alias( const Value *V1, unsigned V1Size, const Value *V2, unsigned V2Size);
判断两个变量是否存在别名关系;
(2) virtual ModRefResult getModRefInfo( CallSite CS1, CallSite CS2);
判断两个函数调用之间的别名关系;
(3) virtual void getMustAliases( Value *P, std::vector<Value*> &RetVals);
获得一定与指针P存在别名关系的变量列表;
(4) virtual bool pointsToConstantMemory( const Value *P);
判断指针是否仅仅指向常数内存
(5)bool doesNotAccessMemory( CallSite CS);
bool onlyReadsMemory( CallSite CS);
判断访问类型。
三、向LLVM中添加一遍新的别名分析优化
1、首先需要确定该遍优化的类型:
别名分析是许多编译优化得以顺利进行的一个前提,也是分析程序特征的一个基础手段。通常而言,别名分析有以下几类:
(1)按是否与控制流相关可分为:flow-sensitive vs flow-insensitive
(2)按是否与上下文相关可分为:context-sensitive vs context-insensitive
(3)按是否与特定领域相关可分为:field-sensitive vs field-insensitive
(4)按实现方式可分为:unification-based vs subset-based
在进行别名分析时,区分别名类型:Must,May,No是十分重要的。由于判定任意变量在运行时是否真的相关的问题,是一个不可判定问题,它等价于图灵机停机问题,所以编译人员无论是对程序进行静态还是动态别名分析,总是存在无法确定的情况。当我们肯定两个变量或者指针的别名是一定存在的则别名类型为Must,若肯定他们是不存在的则别名类型是No,否则只能是May。对May类型的别名关系,我们必须承认它但不能依靠它;而对Must和No类型的别名关系,我们可以充分信任。
关于别名关系的详细理论和更深层次的讨论可以参考Muchnick的《高级编译器设计与实现》和Andersen的博士论文《Program Analysis and Specialization for the C Programming Language》。
二、LLVM接口类 AliasAnalysis
LLVM针对别名关系提出了统一的抽象类 AliasAnalysis,该类定义了各种别名分析需要实现的接口。该类定义了表示别名关系的公共枚举类型: AliasResult and ModRefResult,其定义如下:
enum AliasResult { NoAlias = 0, MayAlias = 1, MustAlias = 2 };
enum ModRefResult { NoModRef = 0, Ref = 1, Mod = 2, ModRef = 3 };
其中定义的接口有:
(1) virtual AliasResult alias( const Value *V1, unsigned V1Size, const Value *V2, unsigned V2Size);
判断两个变量是否存在别名关系;
(2) virtual ModRefResult getModRefInfo( CallSite CS1, CallSite CS2);
判断两个函数调用之间的别名关系;
(3) virtual void getMustAliases( Value *P, std::vector<Value*> &RetVals);
获得一定与指针P存在别名关系的变量列表;
(4) virtual bool pointsToConstantMemory( const Value *P);
判断指针是否仅仅指向常数内存
(5)bool doesNotAccessMemory( CallSite CS);
bool onlyReadsMemory( CallSite CS);
判断访问类型。
三、向LLVM中添加一遍新的别名分析优化
1、首先需要确定该遍优化的类型:
- If you require interprocedural analysis, it should be a Pass.
- If you are a function-local analysis, subclass FunctionPass.
- If you don't need to look at the program at all, subclass ImmutablePass.
void getAnalysisUsage(AnalysisUsage &AU) const {
AliasAnalysis::getAnalysisUsage(AU);
// declare your dependencies here.
}
bool run(Module &M) {
InitializeAliasAnalysis(this);
// Perform analysis here...
return false;
}
3、注意AliasAnalysis chaining和Updating analysis results相关的内容
4、详细可以参考http://www.llvm.org/docs/AliasAnalysis.html