remove struct 伪代码思路

在这里插入图片描述

#include<DAG.h>

struct str {
  x,y;
};

//Convert ConstantExpr as Instruction
//%1 = load volatile i64, i64* getelementptr inbounds (%struct.str, %struct.str* @global, i64 0, i32 1)
//->%1.1 = getelementptr inbounds (%struct.str, %struct.str* @global, i64 0, i32 1);
//  %1 = load volatile i64, i64* %1.1
void ConvertConstantExprToInst(Module &m);

//build StructType's StructTypeDAG, vertex is StructType 
StructTypeDAG *struct_type_DAG = new StructTypeDAG();
//function_list save bc’s function process sequence
list<Function*> function_list;


void TraverseIR(function_list) {
	//firstly, get the Module's Function_List(save the list starting from main)
	(1)unordered_set<Function *> function_set;
	
	//secondly, process each instructions of function
	//get the function_main, traverse the function_main
	(2)TraverseFunctionInstruction(Function *f, function_list);
	 
	 //the result of function_list has repeated elements, just save the first time data by function_set;
	(3)getFunctionList(function_list)
		
	(final_1)function_set.clear()
}

void TraverseFunctionInstruction(Function *f, function_list) {
	for each Instruction of f :
		if (Instruction is AllocaInst with structType) {
			//add the new structType in StructTypeDAG
		} else if (Instruction is CallInst) {
			//go to the called function
			//if the function does not have callInst, put the function into function_list
			TraverseFunctionInstruction(f_call,function_list);
		}
    //traverse all of instructions
	function_list.push_back(f);
}

void RemoveStruct::BuildHierarchyInfo(list<Function*> &function_list) {
  TraverseIdentifiedStructTypes();
  //process the BC to get the function_list & struct_type_DAG
  TraverseIR(function_list);
  struct_type_DAG->printStructType();
}

// the main function of RemoveStruct
void RemoveStruct::RemoveStructMain(){
  //Convert ConstantExpr as Instruction
  ConvertConstantExprToInst();

  //func_list save bc's function process sequence
  list<Function*> func_list;
  BuildHierarchyInfo(func_list);
  
  processStructValue();
}

void processStructValue(Module &m) {
	//save delete values
	list<Value*> delete_list;

	//Correspondence of new value and old value (include function arguments)
	unordered_map<Value *, vector<Value *> > Value_umap;
	
	//uset save the StructType to be processed
	unordered_set<StructType *> uset;
	struct_type_DAG.TopLevelStructType(uset);
	
	while struct_type_DAG->hasTopLevelVertex() {
		void processGlobalVar(uset);
		for each Function of function_list : {
			if (Function in func_umap_) {
				processFuncBody(Mid_func, uset);
			} else {
				processFuncBody(Function, uset);
			}
			
		}
		struct_type_DAG.ProcessTopLevelVertex(uset);
	}
}


void processGlobalVar(uset) {
	for each GlobalVariables of GlobalVariableList:
		//查找StructType *a是否存在,用uset.find(a)
		if(GlobalVariable's Type in uset)
		{
			new gv_x, gv_y :Value_umap.insert(GlobalVariable,vector<Value*>(gv_x,gv_y))
			GlobalVariable insert delete_list
		} else {
			continue;
		}	
}

void processFuncArgu(Value_umap){
	for each arg of Function:{
		if (arg in Value_umap){
			//arg.x, arg.y get from Value_umap.find(arg);
			create new_function(arg.x, arg.y)
			Value_umap.insert(arg, vector<Value*>(arg.x,arg.y))
			Function insert delete_list
		}		
	}
	for each Value of delete_list{
		delete Value
	}	
}

void processFuncBody(Value_umap,Function) {
	for each Value of function:{
		if(Value is variable) {
			if (variable's Type in uset)
			{
				new sub_variable :Value_umap.insert(variable, vector<Value*>(sub_variables))
				variable insert delete_list
			} else {
				continue;
			}
		}
		//start to process the Instructions in function
		//processReslovedValue(inst)
		else if (Value is an operation Instruction) {
			if(Instruction中的input value in Value_umap) {
				if(%1 = LoadInst(str)) {
					//str.x、str.y get from Value_umap.find(str);
					表达方式:%2 = LoadInst(str.x); %3 = LoadInst(str.y); 
					Value_umap.insert(%1, vector<Value*>(%2,%3))
					%1 insert delete_list
				} else if (%1 = GetElementPtrInst(str)) {
					表达方式:%2 = GetElementPtrInst(str.x); 
					Value_umap.insert(%1, vector<Value*>(%2))
					%1 insert delete_list
				} else if (%1 = MemCpyInst(str_1,str_2)) {
					//str_1.x,str_1.y get from Value_umap.find(str_1); str_2.x,str_2.y get from Value_umap.find(str_2);
					表达方式:%2 = MemCpyInst(str_1.x,str_2.x); %3 = MemCpyInst(str_1.y,str_2.y); 
					Value_umap.insert(%1, vector<Value*>(%2,%3))
					%1 insert delete_list
				} else if (%1 = CallInst(str_1,str_2)) {
					表达方式:%2 = CallInst(str_1.x,str_1.y,str_2.x,str_2.y);
					Value_umap.insert(%1, vector<Value*>(%2))
					表达方式:CallFunction(arg_str_1,arg_str_2):分解 arg_str_1:arg_str_1_x,arg_str_1_y  arg_str_2:arg_str_2_x,arg_str_2_y
					Value_umap.insert(arg_str_1, vector<Value*>(arg_str_1_x,arg_str_1_y))
					Value_umap.insert(arg_str_2, vector<Value*>(arg_str_2_x,arg_str_2_y))
					%1 insert delete_list
				} else if (%1 = BitcastInst(str)) {
				  //语句不改变,记录str.x str.y
				  Value_umap.insert(%1, vector<Value*>(%1, str.x, str.y))
				} else if ((%1 = StoreInst(str to dest)) {
					表达方式:%2 = StoreInst(str.x to dest.x); %3 = StoreInst(str.y to dest.y); 
					Value_umap.insert(%1, vector<Value*>(%2,%3))
				}
				//如果当前指令无法分解,就记录该指令及其sub_value信息于Value_umap,等待使用该条指令再分解。
				Instruction insert delete_list
			} else {
				continue;
			}
		}
	}	
}


一、CallInstProcess()
//callInst是最终指令,直接处理,不需要被别人调用。
//callInst A_x,A_y的类型需要与A保持一致,function的同样
callInst(A,B),其中A decompose to A_x,A_y

(1)处理main函数时,中途遇到callInst(A),处理old_func(A)(2)创建有body的Mid_func(A,A_x,A_y)    [func_map(old_func, Mid_func)umap(A, vector(A_x, A_y))]
(3)创建new_func(A_x,A_y)  目的:给callInst生成callInst(A_x,A_y)       [func_map(Mid_func,new_func)]
(4)当function_list遇到old_func时,处理Mid_func,得到最终的Mid_func,只有其参数需删除
(5)替换Mid_func,将其body copy给new_func。 
(6)new_func代替old_func在function_list中的位置  [old_func->eraseFromParent();Mid_func->eraseFromParent()]

拿到一条callInst,需要分解的变量为N个,同时得到N个分解后子变量

(1)需要修改的变量:Type为structure的struct变量 ,其对应处理函数是PointerAsFunctionArg()。
(2)需要修改的变量:Type为iN的struct变量,其对应处理函数是LoadiNAsFunctionArg()

(1)operation为allocaInst或global或argument,都是variable, value_umap_必然保存了该变量。
(2)operation为其他Inst,转入处理

二、LoadInstProcess()
  Value *load_src = inst->getOperand(0);
  if (value_umap_.find(load_src) != value_umap_.end()) {
    if (isVariable(load_src)) {
		assert(0);
    } else {
		//需要处理loadInst+load_src两个指令,分情况讨论。
		if (isa<llvm::BitCastInst>(load_src)) {
			if (load_src return type is iN) {
				//BitcastNextLoadProcess(loadI);
				//%2 = bitcast %1 to iN*
				//%3 = load iN* %2
				首先(%1的Type、iN)得到memoryTable的表,表中存的是sub_value及其lsb与msb
				map_table(%3,memorytable)			
			} else {
				assert(0);
			}
		} else if (isa<llvm::GetElementPtrInst>(load_src)) {
			if (GetElementPtrInst return structType) {
				
			}
		}		
	}
  }

	
二、otherInst(inst){
//shl、lshr、ashr、and、or、xor、trunc、zext、sext
value_umap_.insert(inst,inst) //assert(inst==isnt)
	if (map_table.find(inst)) {
		
	}	
}

二、StoreInstProcess()
	if (Store_src is LoadInst) {
		map_table(LoadInst,memorytable),利用memorytable处理。
	}
	if (Store_dest is BitCastInst) {
		
	}

二、BitCastInstProcess()
	//单独一条指令,无法做任何处理
	//暂时只将bitcastInst放入value_umap_,等待其user处理。
 %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*

	inst_1(inst_2) & map(inst_2,inst_3)// when have inst_1,actually we get inst_2 & inst_3
三、GetElementPtrInstProcess(inst): 
//(1)getelementptrInst中第二个operand不是constantInt 0,则必须保留。
//(2)特殊情况:
  //  %3 = i8* getelementptr inbounds (%struct.str, %struct.str* @global, i32 0, i32 0);
  //  call void @llvm.memcpy.p0i8.p0i8.i64(i8* %2, i8* %3, i64 20, i32 4, i1 true),
  //  can not resolved directly
//(3)注意delete_list_需要搜集的instruction
拿到一个getelementptr,先判断src是否在value_umap_,在判断src是不是variable。
(1)为variable时,判断inst能否分解:
		能分解value_umap_(inst,sub_value)
		不能分解value_umap_(inst,inst)需要下面语句一起处理
(2)不为variable时,是一条instruction
		src_inst在value_umap_中的vector中的inst不是src_inst,说明src_inst已经处理好,不需要再次处理。跳过。
		src_inst在value_umap_中的vector中的inst是src_inst,说明两条语句结合处理。
		处理结果放于vector。能处理完毕就放new_inst,不能就放src_inst自身。等待下次遇到再处理。

	if (value_umap_ find input_val) {
		//写成一个函数
		if (input_val为allocainst或global或argument) {
			if (input_val->isStructType()) {
				if (inst->getNumOperands() > 2) {
					value_umap_.insert(inst,inst_x);
					//GetelementptrStructResloved(inst);
				}
			} else if (input_val->isArrayStructType()) {
				if (inst->getNumOperands() > array_layers + 2) {
					value_umap_.insert(inst,inst_x);
				}
			} else {
				assert(0);
			}
		}

		else {
		//另外一个函数
		//process instructions
		vector<Value *> vec;
		vec = value_umap_.find(input_val);
		input_val = vec.at(0);
			if (isa<llvm::GetElementPtrInst>(input_val)) {
				%3 = input_val + inst;
				if (%3 可以分解出子变量inst_x) {
					value_umap_.insert(inst,inst_x);
				} else {
					value_umap_.insert(inst,%3);
				}
			} else if (isa<llvm::BitCastInst>(input_val)) {
			// %struct.point = type { float, double }
			// %54 = bitcast %struct.point* %0 to { float, double }*
			// %55 = getelementptr inbounds { float, double }, { float, double }* %54, i32 0, i32 0
				//分解出%0的元素
				value_umap_.insert(inst,%0_x);
			} else {
				assert(0);
			}
		}		
	}

二、MemcpyInstrProcess(inst):
	if (value_umap_ find src_val) {
		if (src_val is BitcastInst) {

		} else if(src_val is GetElementPtrInst) {
			//GetElementPtrInstWithMemcpy(inst);
		}	
	}	
	
	if (value_umap_ find dest_val) {
		if (dest_val is BitcastInst) {

		} else if(dest_val is GetElementPtrInst) {
			//GetElementPtrInstWithMemcpy(inst);
		}	
	}	

	 if (st_dest == st_src) process

#include<DAG.h>


class StructTypeDAG {
  private:
	typedef struct TypeMemory {
		Type *ty;
		int LSB;
		int MSB;
		TypeMemory(Type *Ty, int L, int M) {
		  ty = Ty;
		  LSB = L;
		  MSB = M;
		}
	}type_mem;
	
    struct Vertex{
      StructType *struct_Type_;
	  //build edge to children vertex 
      std::unordered_set<Vertex *> vertex_children_;
	  //StructType memoryTable
	  std::unordered_map<int , type_mem> memoryTable;
    };
	
  public:
    // Contructor
    StructTypeDAG() {}
    // Destructor
    ~StructTypeDAG();

	//create graph Vertex
	bool FindStructType(StructType *struct_Type);
    void CreateVertex(StructType *struct_Type);	
	//put zero indegree vertexs's StructType into uset
    void TopLevelStructType(unordered_set<StructType *> &uset);
    void DestroyVertex(unordered_set<StructType *> &uset);
	
  private//bulid hierarchy relationship
    void ConnectVertex(Vertex *parent, Vertex *child) const;
	//look up the position of StructType in DAG
    unordered_map<StructType *, Vertex *> StructType_map_;
};1)外部输入一个StructType *st
	if(!StructTypeDAG_->hasStructType(st)){
		StructTypeDAG_->addStructTypeToDAG(st);
	}2addStructTypeToDAG(StructType *st){
	//new vertex
	1、new_vertex = CreateVertex(st);
	//build relationship between struct_type & new_vertex
	2、StructType_map_.insert((struct_type, new_vertex));
	//Perfect information of new_vertex
	//info: vertex_parent & vertex_children & memoryTable & alignment & length
	3CreateVertexMemoryTable(Vertex *new_vertex);
	}
 //此时StructTypeToDAG相关信息全部建完。3//uset saves all top level StructType of DAG
	unordered_set<StructType *> &uset;
	StructTypeDAG_->TopLevelStructType(uset); 

(4//delete all info of uset's vertexs, uset.clear()
    StructTypeDAG_->DestroyTopLevelVertex(uset)
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值