c++使用python,c程序和python
本文主要介绍如何使用Python实现简单C程序的作用域分析。文章通过实例和流程实现思路进行了阐述,具有一定的参考价值。有需要的小伙伴可以参考一下,希望对你有帮助。
00-1010 1.实验描述2。项目用途3。算法原理3.1构建CFG3.2构建约束图3.3构建E-SSA约束图3.4三步法3.4.1加宽3.4.2未来分辨率缩小4。实验结果5。摘要
目录
对于以问题要求:静态单赋值(SSA)形式输入的函数中间代码,输出函数返回值的范围。
实现思路:根据2013年CGO会议提出的“三步法”范围分析法[3]基本实现了,得出了各个变量的范围。
算法优势:s空间复杂度和时间复杂度均为O(n),具有较高的效率。
瓶颈:“三步法”的作用有很大的局限性。它只能分析每个变量的最大范围,只对活动变量做最简单的考虑。所以最终的范围是不准确的,只能得到范围的一个边界。
1. 实验说明
Python.py (SSA文件路径在main.py中设置)
不需要安装任何库。
2. 项目使用
采用简单概括:s三步法(2013年CGO会议上提出)
3. 算法原理
code: src essaconstraintgraph . py;srcstructure.py
功能:解析SSA并建立CFG。
由于函数之间的调用关系,SSA首先分为不同函数的SSA,然后单独构建CFG。CFG保留了每个函数的语句和块之间的关系,为下一步构造约束图奠定了基础。
CFG的结构如下:
# CFG类
CFG:级
def __init__(self):
self.name=
自我。Blocks=[]
自我。Edges=[]
自我。参数=[]
3.1 构建CFG
代码:
三步法的前提是构造约束图。数据结构如下。在这一步中,我使用我自己的数据类型MyNode来表示一个约束。
#约束图形类
类约束图:
def __init__(self,cfg):
自我。MyNodes=[] #基本节点,每个节点都是一个约束
自我。MyConditions=[] #用于补充后面E-SSA约束图的条件。
self.cfg=cfg
自我。Arguments=[] #输入参数
Self.returnName= #输出参数
# MyNode :约束图的节点,即
是保存变量范围的地方
class MyNode:
def __init__(self, t= "", name = "", args = [], result = [], fromBlock = 0, Statement = ):
self.type = t #节点类型:leave 叶节点存放范围和值 #op运算符 #var变量名
self.name = name.strip() #节点名称:运算名称,或变量名称
self.args = args #参数,一个节点是另一个节点的argument,意味着二者之间有边相连
self.result = result #被用到哪,一个节点是另一个节点的result,意味着二者之间有边相连
self.Conditions = [] #约束条件, 在后面E-SSA Constraint Graph中补充条件
self.fromBlock = fromBlock #在CFG的哪个Block中定义的
self.Statement = Statement #在SSA中的哪条Statement中
self.Range = Range() #节点范围
self.size =
self.input = False
# Range由两个Bound组成
class Range:
def __init__(self ):
self.lowBound = Bound()
self.highBound = Bound()
# Bound由值和类型组成
class Bound:
def __init__(self):
self.value = None # inf 最大值 ; -inf 最小值; None 未设置; Not Exists 不存在
self.size = None #边界是 int or float
需要注意的是,在解决两个函数之间的调用关系时,将被调用的函数**内联进原函数**。我将被调用的函数的所有变量名都加入相应的后缀,比如`foo`调用`bar`函数,那么`bar`中的变量`i_1`将被更名保存为`i_1#bar$1`,其中#是变量原名和后缀分割符,$是函数名和一个随机数的分割符,$的作用是为了区分多次调用同一个函数的情况。
3.3 构建E-SSA Constraint Graph
代码:`srceSSAConstraintGraph.py`
这一步用于解决条件的添加。诸如`if (i_2 < j_3)`
这样的条件。在MyNode节点类型中,我设置了Conditions结构用于保存条件。Condition
的数据结构如下:
Class Description : Constraint Graph
中的条件,附加在MyNode中
class MyCondition:
其中,arg1和arg2分别表示条件的两个参数,op表示条件的比较运算符。在Future Resolution
这一步会进行比较,进行范围的约束。
以t7.ssa为例,得到的E-SSA Constraint Graph如下:
call bar$1 in 2 : Arguments: i_2,Result: Conditions:
3.4 三步法
3.4.1 Widen
代码:`srcrangeAnalysis.py`
Widen
步骤用于将 变量范围扩大。此步骤可以在O(n)阶段内完成。基于原理如下:可以形象的理解为:在进行Φ操作时,如果发现变量范围向上增加,就直接扩大到inf,如果发现变量范围向下减小,就直接减小到-inf。
这样下来后,每一个MyNode
的范围都会扩大到最大。
3.4.2 Future Resolution & Narrow
代码:`srcrangeAnalysis.py`
在Widen步骤中,只能解决每一个变量内部之间的赋值行为,在Future Resolution
步骤,可以对变量之间的运算、以及条件进行处理。
我用了复杂的`ConditionHandle()
`函数来解决条件变量的Constraint问题。我在每一个MyNode中添加了Conditions结构,用Condition约束来代替变量替换。这样可以大大减少变量替换带来的麻烦。
在`ConditionHandle()
`中,我将条件拆分成`arg1` `arg2`和`op`三部分,将他们组合成条件为真的范围,和条件为假的范围。并把相应的范围赋给相应的变量,以及检查此路径是否可以相通。
以`t7.ssa`为例,三步法得到的所有变量的范围如下:
Enter Range For i: -10 10
可以直接得到结果变量_7的范围为:_7 int int Range: 5 30
4. 实验结果
# t1.SSA
5. 总结
在本实验中,我采用python语言对SSA形式的C程序进行解析,并采用三步法针对特定输入进行了相应的范围分析。收货了写代码的乐趣,也为最后的效果遗憾。
最后的效果中,10个benchmark
的结果中准确结果寥寥无几。尤其是上界,很多都直接到无穷了。这一方面是为了追求时间效率和空间效率,放弃了模拟执行采用三步法的缺陷,另一方面也是因为我没有想到合适的改进方法。
到此这篇关于如何利用Python实现简单C++程序范围分析的文章就介绍到这了,更多相关Python实现简单C++程序范围分析内容请搜索盛行IT软件开发工作室以前的文章或继续浏览下面的相关文章希望大家以后多多支持盛行IT软件开发工作室!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。