当前位置: 首页 > news >正文

天津做不锈钢的网站小公司做网站多少钱

天津做不锈钢的网站,小公司做网站多少钱,c 网站开发培训,管件网络销售怎么找客户本文主要用于记录在活跃变量分析实验中的报错及解决#xff0c;涉及静态测试的详细原理内容较少#xff0c;编译运行底层逻辑偏多。 一、实验要求 1#xff09;使用llvm基于框架实现一个基于WorkList的活跃变量分析demo。变量在某个程序点有两种状态#xff0c;live 或 dea… 本文主要用于记录在活跃变量分析实验中的报错及解决涉及静态测试的详细原理内容较少编译运行底层逻辑偏多。 一、实验要求 1使用llvm基于框架实现一个基于WorkList的活跃变量分析demo。变量在某个程序点有两种状态live 或 dead。对于变量 x 和程序点 p判断 x 在点 p 上的值是否会在 CFG 中的某条从点 p 出发的路径中使用。如果是就说 x 在 p 上 live否则就说x在p上是 dead。 目前本实验假设的输入程序当中只有整型变量即没有浮点、指针、结构、枚举、数组等。 即实现LivenessAnalysis中的如下函数: void LivenessPass::flowIn(Instruction *Inst, BitVector InVec)void LivenessPass::flowOut(Instruction *Inst, BitVector Pre, BitVector Post)BitVector LivenessPass::transfer(Instruction *Inst)void LivenessPass::InstAnalysis() 这些函数对应如下Worklist算法当中的如下四个部分 活跃变量分析为后向的数据流分析本实验实现的demo将通过一个Worklist的大循环对LLVM IR当中的每条指令进行活跃变量的计算其中计算的结果将以llvm::BitVector的形式存储在std::mapValue *, BitVector INSet\OUTSet当中。 上述输出为最终预期的输出结果其中右侧为每个指令对应的活跃变量分析结果以 [ INSet[inst] -- OUTSet[inst] ]形式表现且由于是后向分析所以最后右侧的输出结果是从下到上的形式表现的。 二、实验内容 2.1实验环境 2.1.1环境配置: 安装LLVM 10.0.1: ##llvm10.0.1安装wget https://github.com/llvm/llvm-project/archive/llvmorg-10.0.1.tar.gztar -zxvf llvmorg-10.0.1.tar.gzcd llvm-projectmkdir build cd buildcmake -DCMAKE_BUILD_TYPERelease  -DLLVM_ENABLE_PROJECTSclang -G Unix Makefiles -DCMAKE_INSTALL_PREFIXllvm_install_dir ../llvmmake -j 4 ##4为编译运行时的线程数sudo make install ##若未安装到默认目录当中需要在~/.bashrc当中添加路径sudo gedit ~/.bashrc##在文本末尾添加export PATH$PATH:llvm_install_dir/bin##更新shell:source ~/.bashrc 安装完环境后在实验框架目录下执行以下指令编译运行 mkdir buildcd buildcmake ..make 若能够编译成功你将在build目录下见到LivenessPass.so。 之后在test目录下运行./auto.sh test01得到以下输出 Running Liveness on mainBitVec map:Liveness Analysis Result:  %retval alloca i32, align 4:                        [  --  ]  %a alloca i32, align 4:                             [  --  ]  %b alloca i32, align 4:                             [  --  ]  %c alloca i32, align 4:                             [  --  ]  %d alloca i32, align 4:                             [  --  ]  store i32 0, i32* %retval, align 4:                   [  --  ]  %0 load i32, i32* %a, align 4:                      [  --  ]  %1 load i32, i32* %b, align 4:                      [  --  ]  %add add nsw i32 %0, %1:                            [  --  ]  store i32 %add, i32* %d, align 4:                     [  --  ]  %2 load i32, i32* %d, align 4:                      [  --  ]  store i32 %2, i32* %b, align 4:                       [  --  ]  %3 load i32, i32* %a, align 4:                      [  --  ]  store i32 %3, i32* %c, align 4:                       [  --  ]  ret i32 0:                                            [  --  ] 2.1.2环境情况: Ubuntu: Linux: Llvm: 2.2 flowIn实现 2.2.1文件框架 // Inst:当前处理的Inst; InVec:当前处理的Inst的前一轮分析的Input Bitvectorvoid LivenessPass::flowIn(Instruction *Inst, BitVector InVec) {///TODO 将所有上一个Inst由于是后向分析所以是当前Inst的后继Inst的Output Bitvector进行join操作作为当前Inst的Input Bitvectorauto successors getSuccessors(Inst);BitVector InputVec InVec;// 遍历后继指令并进行合并操作for (auto successor : successors) {BitVector OutputVec OUTSet[successor];InputVec | OutputVec;}INSet[Inst] InputVec;// 将合并后的结果设置为当前指令的输入位向量 } LivenessPass::flowIn(Instruction *Inst, BitVector InVec): 这是一个成员函数用于计算指定指令 Inst 的输入位向量 InVec。输入位向量 InVec 表示在 Inst 执行之前活跃的变量集合。函数的目标是将所有 Inst 的后继指令的输出位向量进行合并join操作得到 Inst 的输入位向量。 auto successors getSuccessors(Inst);: 获取 Inst 的所有后继指令。在控制流图中后继指令是指在控制流中直接跟随 Inst 的指令。 BitVector InputVec InVec;: 创建了一个新的位向量 InputVec它是 InVec 的副本用于存储 Inst 的最终输入位向量。 for (auto successor : successors) { ... }: 这个循环遍历 Inst 的所有后继指令。对于每个后继指令它获取其输出位向量 OutputVec这是在 successor 执行之后活跃的变量集合。 InputVec | OutputVec;: 执行位向量的逻辑或操作将 OutputVec 合并到 InputVec 中。合并操作是将所有后继指令的输出位向量合并到当前指令的输入位向量中表示这些变量在 Inst 执行之前也是活跃的。 INSet[Inst] InputVec;: 计算得到的输入位向量 InputVec 存储在 INSet 映射中INSet 用于存储每个指令的输入位向量。 bool bitVectorsEqual(const BitVector vec1, const BitVector vec2): 用于比较两个位向量是否相等。它首先检查两个位向量的长度是否相同如果不同则它们不相等。然后它遍历位向量的每个位如果发现任何不匹配的位则返回 false。如果所有位都匹配则返回 true 2.3 flowOut实现 void LivenessPass::flowOut(Instruction *Inst, BitVector Pre, BitVector Post){ ///TODO //判断当前输出的Output Bitvector和上一轮迭代的Output Bitvector是否一致 //如果不一致就将当前Inst的所有下一个Inst由于是后向分析所以是当前Inst的前继Inst加入InstVector当中if(bitVectorsEqual(Pre,Post) ){//Pass;}else{auto nextnodes getPredecessors(Inst);for(auto eachnodes : nextnodes)InstVector.push_back(eachnodes);}OUTSet[Inst] Post;//? } void LivenessPass::flowOut(Instruction *Inst, BitVector Pre, BitVector Post): 这个成员函数接受三个参数Inst 是当前正在处理的指令Pre 是指令执行前的位向量即输入位向量Post 是指令执行后的位向量即输出位向量。 if(bitVectorsEqual(Pre, Post)): 用于检查当前指令的输出位向量 Post 是否与上一轮迭代的输出位向量 Pre 相同。如果它们相同说明对于当前指令的输出位向量没有新的信息因此不需要进行任何操作。 else: 如果输出位向量发生了变化即 Pre 和 Post 不相同那么需要更新依赖于当前指令的其他指令的活性信息。 auto nextnodes getPredecessors(Inst); 获取当前指令的所有前继指令。for(auto eachnodes : nextnodes) InstVector.push_back(eachnodes); 将这些前继指令加入到 InstVector 中这是一个待处理的指令列表用于后续的迭代。OUTSet[Inst] Post;: 更新当前指令 Inst 的输出位向量 OUTSet 为新的值 Post。OUTSet 是一个映射用于存储每个指令的输出位向量。 2.4 transfer实现 BitVector LivenessPass::transfer(Instruction *Inst) {// 实现活跃变量分析的转移函数// 初始化Use和Def集合BitVector Use BitVector(InstCounter, false);BitVector Def BitVector(InstCounter, false);// 根据指令类型进行分类处理if (auto *BinOp dyn_castBinaryOperator(Inst)) {Value *Operand0 BinOp;Value *Operand1 BinOp-getOperand(0);Value *Operand2 BinOp-getOperand(1);Def[InstBitMap[Operand0]] true;if (!isImmutable(Operand1))Use[InstBitMap[Operand1]] true;if (!isImmutable(Operand2))Use[InstBitMap[Operand2]] true;} else if (auto *Load dyn_castLoadInst(Inst)) {Value *Operand0 Load;Value *Operand1 Load-getOperand(0);Def[InstBitMap[Operand0]] true;if (!isImmutable(Operand1))Use[InstBitMap[Operand1]] true;} else if (auto *Store dyn_castStoreInst(Inst)) {Value *Operand0 Store-getOperand(0);Value *Operand1 Store-getOperand(1);Def[InstBitMap[Operand1]] true;if (!isImmutable(Operand0))Use[InstBitMap[Operand0]] true;} else if (auto *Alloc dyn_castAllocaInst(Inst)) {Value *Operand0 Alloc;Def[InstBitMap[Operand0]] true;} else if (auto *Cmp dyn_castICmpInst(Inst)) {Value *Operand0 Cmp;Value *Operand1 Cmp-getOperand(0);Value *Operand2 Cmp-getOperand(1);Def[InstBitMap[Operand0]] true;if (!isImmutable(Operand1))Use[InstBitMap[Operand1]] true;if (!isImmutable(Operand2))Use[InstBitMap[Operand2]] true;}// 计算输出活跃变量集合BitVector Out BitVector(InstCounter, false);BitVector Temp INSet[Inst];for (int i 0; i Temp.size(); i) {if (Def[i])Temp[i] false;}for (int i 0; i Use.size(); i) {if (Use[i] || Temp[i])Out[i] true;}return Out; } 这段代码是一个活跃变量分析Liveness Analysis的迁移函数transfer的实现。迁移函数用于计算在执行当前指令后哪些变量是活跃的。活跃变量是指在指令执行后仍然有效的变量它们可能是使用Use或定义Def的变量。 代码的主要部分是针对不同类型的指令二元运算符、加载指令、存储指令、内存分配指令、比较指令的分支处理。对于每种类型的指令代码会更新Use和Def集合然后使用这些集合来计算输出活跃变量集合。 BitVector Use BitVector(InstCounter, false); 和 BitVector Def BitVector(InstCounter, false);: 这两行代码初始化了两个位向量 Use 和 Def它们分别用于表示指令的“使用”集合和“定义”集合。InstCounter 是指令的数量用于确定位向量的长度。初始化时位向量的所有位都设置为 false。 if (auto *BinOp dyn_castBinaryOperator(Inst)) { ... }: 这段代码处理二元运算符指令。dyn_cast 是一个类型转换函数用于安全地将指令转换为 BinaryOperator 类型。如果转换成功说明当前指令是一条二元运算符指令。 对于二元运算符它的结果Operand0被加入到 Def 集合中表示这个指令定义了结果值。如果操作数Operand1 和 Operand2不是不可变的isImmutable 返回 false则它们被加入到 Use 集合中表示这些操作数被使用了。 else if (auto *Load dyn_castLoadInst(Inst)) { ... }: 这段代码处理加载指令Load。加载指令的结果被加入到 Def 集合中表示这个指令定义了加载的值。加载指令的源操作数Operand1如果是可变的则被加入到 Use 集合中。 else if (auto *Store dyn_castStoreInst(Inst)) { ... }: 处理存储指令Store。存储指令的目标操作数Operand1被加入到 Def 集合中表示这个指令定义了存储的目标。存储指令的源操作数Operand0如果是可变的则被加入到 Use 集合中。 else if (auto *Alloc dyn_castAllocaInst(Inst)) { ... }: 处理分配指令Alloca。 分配指令的结果被加入到 Def 集合中表示这个指令定义了分配的内存。 else if (auto *Cmp dyn_castICmpInst(Inst)) { ... }: 处理比较指令ICmp。 比较指令的结果被加入到 Def 集合中表示这个指令定义了比较的结果。 比较指令的操作数Operand1 和 Operand2如果是可变的则被加入到 Use 集合中。 BitVector Out BitVector(InstCounter, false);: 初始化了输出位向量 Out它将用于存储当前指令执行后的活跃变量集合。 BitVector Temp INSet[Inst];: 获取了当前指令的输入位向量 INSet[Inst]并将其存储在临时位向量 Temp 中。 for (int i 0; i Temp.size(); i) { ... }: 遍历临时位向量 Temp如果某个位在 Def 集合中为 true则将该位在 Temp 中设置为 false。 这是因为如果一个变量在当前指令中被定义那么它之前的活跃状态就不重要了。 for (int i 0; i Use.size(); i) { ... }: 遍历 Use 集合如果某个位在 Use 集合中为 true 或者该位在 Temp 中为 true则将该位在 Out 中设置为 true。 这表示这个变量在当前指令执行后仍然是活跃的。 return Out;: 最后返回输出位向量 Out它表示当前指令执行后的活跃变量集合。 2.5 InstAnalysis实现 初次尝试: 结果: 更新后,成功!: void LivenessPass::InstAnalysis() {///TODO///基于实现基本的WorkList循环,使用你刚刚实现的flowIn, flowOut, transfer函数实现活跃变量分析while (!InstVector.empty()){auto instruction *InstVector.begin(); // 获取指向 Value* 的指针,注意*号否则返回的是迭代器Instruction *Inst dyn_castInstruction(instruction);InstVector.erase(InstVector.begin());if (Inst) // 确保转换成功{BitVector Pre OUTSet[instruction];flowIn(Inst, INSet[instruction]);OUTSet[instruction] transfer(Inst); //transfer函数导致段错误flowOut(Inst, Pre, OUTSet[instruction]);} 代码解释如下 void LivenessPass::InstAnalysis(): 成员函数用于执行活跃变量分析。 for (auto instIterator InstVector.begin(); instIterator ! InstVector.end(); ): 遍历指令集合 InstVector。 InstVector 是一个待处理的指令列表包含了在活跃变量分析中需要考虑的指令。 Instruction *Inst dyn_castInstruction(*instIterator);: 尝试将迭代器指向的元素转换为 Instruction 类型的指针。 dyn_cast 是一个类型转换函数用于安全地将迭代器指向的元素转换为 Instruction 类型。 instIterator InstVector.erase(instIterator);: 如果转换成功这行代码从 InstVector 中移除当前指令。 移除操作通常发生在指令被处理后以确保在后续迭代中不会重复处理同一个指令。 if (Inst) // 确保转换成功: 用于确保转换成功即当前迭代器指向的元素确实是一个指令。 BitVector preOut OUTSet[Inst];: 获取当前指令的输出位向量 preOut。 OUTSet 是一个映射用于存储每个指令的输出位向量。 flowIn(Inst, INSet[Inst]);: 调用 flowIn 函数计算当前指令的输入位向量。 INSet 是一个映射用于存储每个指令的输入位向量。 OUTSet[Inst] transfer(Inst);: 更新当前指令的输出位向量。 transfer 函数用于计算指令的输出位向量即在该指令执行后活跃的变量集合。 flowOut(Inst, preOut, OUTSet[Inst]);: 调用 flowOut 函数计算当前指令的前继指令的输出位向量。 preOut 是当前指令在执行前的输出位向量OUTSet[Inst] 是当前指令在执行后的输出位向量。 2.6 测试结果 三、补充内容 报错no LivevessPass.so .SO文件是共享对象文件Shared Object File的缩写它是一种用于链接的文件格式其中包含了可执行代码和数据这些代码和数据可以被多个程序共享。.SO文件通常用于Unix-like操作系统如Linux它们用于动态链接允许应用程序在运行时链接到这些文件而不是在编译时链接。 这让我想起来之前学习时用的.a静态库查阅资料发现: .SO文件 文件扩展名.so共享对象适用平台Unix-like操作系统如Linux文件内容.so文件包含动态链接库Dynamic Link Library的代码和数据它们可以在程序运行时被加载到内存中。.so文件通常用于提供扩展功能如图形库、网络库等。.a文件 文件扩展名.a静态链接库适用平台Unix-like操作系统如Linux文件内容.a文件包含静态链接库的代码和数据它们在编译时被链接到程序中而不是在运行时。.a文件通常用于提供基础功能如标准库。.dll文件 文件扩展名.dll动态链接库适用平台Windows操作系统文件内容.dll文件包含动态链接库的代码和数据它们可以在程序运行时被加载到内存中。.dll文件通常用于提供扩展功能如图形库、网络库等。 在功能上.SO和.dll文件都是用于动态链接的库文件而.a文件是用于静态链接的库文件。静态链接和动态链接的主要区别在于静态链接将库文件的内容直接合并到可执行文件中而动态链接则将库文件作为外部依赖在运行时加载。相关性方面.SO和.dll文件都是为了在运行时提供扩展功能而.a文件则提供了基础功能。在实际应用中.SO和.dll文件可以被看作是.a文件的动态版本它们提供了相同的库功能但以不同的方式集成到应用程序中。 解决1 原因是没有camke .. 和make编译….. 相关资料学习: CMake: 用途: CMake是一个跨平台的构建系统生成器它用于生成可执行的构建系统如Makefile。生成: CMake不直接构建项目而是生成一个构建系统如Makefile或Ninja构建文件然后使用Make或Ninja来构建项目。平台: CMake支持多种平台包括Windows、macOS和Linux。配置: CMake通过一个名为CMakeLists.txt的配置文件来定义项目配置包括依赖关系、编译选项等。构建系统: CMake生成的构建系统如Makefile可以由Make或Ninja使用来构建项目。Make: 用途: Make是一个构建工具用于自动化编译过程。直接构建: Make直接构建项目根据Makefile中的规则和依赖关系来编译源代码。平台: Make在Unix-like操作系统中广泛使用但在其他平台上也有替代品。构建系统: Makefile是由Make使用来构建项目的文件它定义了项目的依赖关系和编译规则。 成功解决。 报错2 make报错代码内变量未定义 尝试2.1:改头文件(and make文件里的include) 看到众多未定义我以为是头文件库的包含有误 改动为 但无效查看发现 已经包含了 include_directories(${LLVM_INCLUDE_DIRS} include)将LLVM的头文件目录和项目中的include目录添加到编译器的头文件搜索路径中。 解决2 实际是我的代码编写有误,确实没定义该内容;应该是livenesspass; 报错 ./auto.sh 脚本内对输入处理有误 解决3:先输入一个符号避免报错,随后输入测试文件名; Cat查看内容,如下: 同样需要换行后才能输入(为什么?) 报错4:./auto.sh执行完没有输出: 尝试4.1:print函数是否修改 教辅表示查看print,但是我并没有改动过其他print函数的文件. 解决4: 恢复原auto.sh 恢复原auto.sh.查看区别: 34行的cd原因见【报错5】测试路径是在/myshixun下 56行是把正确和错误输出都重定向到null 第9行是问题关键:   没有-Liveness是没有正确输出的 opt 是 LLVM 优化器的一个命令行工具它用于对 LLVM IR中间表示进行各种优化。LivenessPass.so 是一个共享库它包含了一个自定义的 LLVM pass优化过程这个 pass 被命名为 Liveness。 寻找Liveness两个文件下找到 加入Liveness后成功得到输出: 报错头哥平台评测错误 报错显示没有LivenessPass.so这个共享库类似动态库 根据之前的试错中得知这个是make后生成的----定位错误到make环节 解决5 pwd先看本地路径是什么 发现是失败即代码有误见报错 细看,发现报错是中括号中的变量处理有误: 对比成功代码,发现是: 我使用迭代器instIterator来访问InstVector中元素并使用它作为OUTSet和INSet的索引。而std::map不支持使用迭代器作为索引。 应该使用Inst作为索引因为Inst是一个指向Instruction的指针这是OUTSet和INSet中键的类型 且这里的代码也同样出错【InstVector是向量vector,erase操作没有返回值】   探索6命令行输出不一 发现: 此处make时只有2个cpp.o 而之前都是4个: 尝试在更改一个cpp文件后直接make:---发现只有一个cpp.o---说明只会重新make更改过的文件【除非make clean 了 会重新make所有】 报错7段错误【代码导致的】 是指针处的问题具体细节见前面【报错 4】
http://www.hkea.cn/news/14470262/

相关文章:

  • 北京seo网站内部优化潍坊建设gc局网站
  • 哪些免费的网站可以做企业宣传工作图片
  • 西宁网站推广网站没更新
  • 青岛即墨网站开发wordpress必备工具
  • 仪征建设局网站网页翻译功能
  • 营销型网站建设题库宁夏建设厅网站官网
  • jsp做电影网站wordpress在文章中加背景
  • 国外化工网站模板做推广网站多少钱
  • 怎么做地下彩票网站天元建设集团有限公司六大板块
  • 电商网站如何生成app网站做防篡改
  • 正规的无锡网站建设wordpress验证
  • 企业做电商网站建好网站后最怎么维护
  • 做教育的网站有哪些内容吗嘉定专业做网站
  • 做网站去哪里备案大学生网站的设计风格
  • 在线网站代理浏览适合0基础网站开发软件
  • 网站开发 0755邯郸网站建设好的公司
  • 快速建站代理wordpress 主题放在哪
  • 北京人力资源网站深圳官方网站设计
  • 缠绕机东莞网站建设技术支持微商城网站开发
  • 新浪网站制作上海建筑建材业网官网入口
  • 伊春网站优化wordpress首页等待画面
  • 想做企业网站想让客户公司做网站的话语
  • 外包网站建设互联网技术主要学什么
  • 江苏省 建设 注册中心网站首页营销型网站建设网站建设制作
  • 橙色网站模板ghost卸载wordpress
  • 网站开发 就业简历模板网站建设必须要服务器么
  • 网商网优化服务
  • 局域网怎么建设网站外贸自建站有哪些
  • 个人自己免费建网站哪家手机网站建设
  • 为什么要做网站优化开源的网站开发软件