2020-01-17rm_struct总结文档

代码总框架:
一、第一层函数 :RemoveStructMain()
其中changBC是主要处理函数,函数findStruct()是用于检测BC文件是否存在structType,以后会用while循环处理。

void RemoveStruct::RemoveStructMain(){
  changeBC();
  if (findStruct()){
    cout<<"RemoveStructMain(): exist structure value!"<<endl;
    changeBC();
  } else {
    outs() << "RemoveStructMain(): Success!  " << "\n";
  }
}

二、第二层函数:changeBC()
第一个函数pretreatment()对bc进行预处理,将BC中组合语句split开,方便后续处理。
第二个函数
getIRStructType()是对module中所有定义的StructTypes进行读取,并将其与其分解出的StructType都存入DAG中。
第三个函数
SaveRootGlobalVar();
Traverse the module_ global list to find structure gv and save gv in structDAG
(DAG由多个vertex组成)

    struct Vertex{
      StructType *struct_Type_;
      std::map<Value *, vector<Value *> > vertex_value_;
      // vector<Value *> is the resolved values of Value
      std::set<Vertex *> vertex_children_;
      std::set<Vertex *> vertex_parent_;
    };

第四个函数AllocaInstr(); Traverse the module_ allocaInst list to find structure allocaInst and save allocaInst in structDAG
以上全部为构建DAG为处理struct做准备。
第五个函数TopologicalSort(); 通过SaveRootGlobalVar();和 AllocaInstr();这两个函数已经把struct value都存入DAG,下一步则是分解处理。

void RemoveStruct::changeBC() {
  //split instruction for serving process struct
  while (pretreatment()) {};
  if(findStruct()){
    getIRStructType();
    SaveRootGlobalVar();
    AllocaInstr();
    StructDAG_->printStructType();
    cout<<"DAG construction completed!"<<endl;
    TopologicalSort();
    //DelUnuseGlobalVarAndAlloca();
  }
//assert(findStruct());
//valueMapPrint();
}

三、第三层函数:TopologicalSort()
(1)遍历DAP中的vertex,找出入度为零的vertex,并将其存入队列q。

  queue<StructDAG::Vertex*> q;
  //q storage vertexs which's indegree are zero
  StructDAG_->FindZeroIndegreeVertex(q);

(2)对每个vertex中的struct value进行分解替换处理,并将该struct value删除。

  while (!q.empty()) {
    StructDAG::Vertex *v = q.front();
    q.pop();
    //process p
    //(2.1)renew the current vertex relations with others
    //(2.2)process structure values in current vertex
    }

(2.1)当前的vertex V入度为零,对其children vertex进行遍历,renew the current vertex relations with its children,children vertex入度为零 push至queue。最后将V的children vertex set清空。
(ps此时V上两个set清空,只有map上的 std::map<Value *, vector<Value *> > vertex_value_;)

(2.2)
firstly,对同类型StructType的vertex V中所有Value进行resolveValue,此时当前subValue已得到。

secondly,此时已经将Value分解完毕,sub_value在其children vector上,通过user对Value相关指令进行替换和修改。并将V中map上的处理完毕的Value存入list。
(其中有两次processVertexValue(iter->first);第一次是正常处理BC中原本的struct,第二次是为了处理我在处理第一次struct生成与struct相关instruction。)

thirdly,通过list删除所有的Value,对当前的V的map进行清空,对有效位的set进行clear。

(3)
函数function_map_process()为了删除oldFunction,然后对StructDAG进行clear。此时将生成最终无struct的BC。

  function_map_process();
  StructDAG_->printStructType();
  StructDAG_->DestroyVertex();

四、第四层函数: processVertexValue()
主要处理一下五个函数,对应的五条指令都是由DAG上的struct value遍历找到的instruction。
在这里插入图片描述
(一)首先处理GetElementPtrInstProcess()函数。
分情况讨论:
1、当GetElementPtrInst的getOperand(0)为IsStructVal时
情况一:NumOperands为2时,assert。
情况二:NumOperands > 2时,进行GetelementptrStructProcess(instr),该函数就是将subValue代替structValue。
2、当GetElementPtrInst的getOperand(0)为IsArrayStructVal时
进行GetelementptrArrayProcess(instr, array_layers);array_layers为当前array层数。
情况一:instr->getNumOperands() < array_layers + 2,

// %120 = getelementptr inbounds [2 x [2 x %struct.point]], [2 x [2 x %struct.point]]* @global_8, i64 0, i64 1
// %121 = bitcast [2 x %struct.point]* %120 to i16*

getelementptr +bitcast 进行BitCastInstProcess(inst);

//%3 = getelementptr inbounds [2 x %struct.str], [2 x %struct.str]* %1, i64 0, i64 0
//%4 = call fastcc i32 @sum(%struct.str* nonnull %3) #4

getelementptr +call 进行GetElementPtrInstAsCallInstProcess(call_inst, instr);
未写代码打算参考callprocess()进行嫁接
情况二:instr->getNumOperands() == array_layers + 2

// %52 = getelementptr inbounds [2 x %struct.point], [2 x %struct.point]* %global_0, i64 0, i64 1
// %53 = bitcast %struct.point* %52 to i16*

getelementptr +bitcast 进行BitCastInstProcess(inst);

//%3 = getelementptr inbounds [2 x %struct.str], [2 x %struct.str]* %1, i64 0, i64 0, i64 0
//%4 = call fastcc i32 @sum(%struct.str* nonnull %3) #4

getelementptr +call 进行GetElementPtrInstAsCallInstProcess(call_inst, instr);
未写代码打算参考callprocess()进行嫁接

//%47 = getelementptr inbounds %struct.str, %struct.str* %0, i64 0, i32 8
//%48 = getelementptr inbounds [2 x %struct.point], [2 x %struct.point]* %47, i64 0, i64 0, i32 0

进行DoubleGetElementPtrProcess()两条指令进行合并,却没有进行分解替换。
看看情况一情况二是否可以合并!!
情况三:正常情况分解。

//  %6 = getelementptr inbounds [2 x [2 x %struct.str]], [2 x [2 x %struct.str]]* @global, i64 0, i64 0, i64 0, i32 0

3、未发现StructType,assert(0),情况不可能。

(二)其次处理MemcpyInstrProcess()函数。
取出需要copy的目标value memcpy_dest。memcpy比较独立。

  // get IntrinsicInst op_0 memcpy_dest
  Value *memcpy_dest = MemcpyDestValue(instr);

memcpy_src分情况讨论:
情况一:memcpy_src is ConstantExpr
MemcpyToConstantExpr(memcpy_dest, instr_src, instr);

情况二:memcpy_src is GetElementPtrInst
memcpyToGetElementPtrInst(memcpy_dest, getelementptr_src, instr);

情况三:memcpy_src is BitCastInst
memcpyToBitCast(memcpy_dest, bitcast_src, instr);

(三)接着处理LoadInstProcess()函数。
只有一种情况:
load的参数为ConstantExpr
ConstantExpr可以分为bitcast和GetElementPtr,但是一般bitcast在预处理split开了,load中会存在GetElementPtr。直接用GetElementPtrInstProcess(get_inst);处理一下就好。

(四)再处理BitCastInstProcess()函数。
遍历BitCastInst的user种类
情况一:BitcastNextLoadProcess(),重点。
情况二:MemcpyInstrProcess();用之前的处理函数。
情况三:StoreInstProcess(),这个就是做拼接指令的。

(五)最后处理FunctionProcess()函数。
存在于callInst中的structValue,通过callInst找到对应的Function,

llvm::CallInst *inst = llvm::dyn_cast<llvm::CallInst>(CI);
CollectFunctionList(inst, FunctionList, val);

CollectFunctionList():structValue->CallInst->Function->CallInsts
这种需要修改,修改为先用function_map_记录新旧Function,最后进行删除旧的Function。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值