mem2reg流程基本跑通,修复phi函数打印,需要删除调试print
This commit is contained in:
241
src/Mem2Reg.cpp
241
src/Mem2Reg.cpp
@@ -46,42 +46,116 @@ std::unordered_set<BasicBlock *> Mem2Reg::computeIterDf(const std::unordered_set
|
|||||||
* 这里的value2AllocBlocks、value2DefBlocks和value2UseBlocks改变了函数级别的分析信息
|
* 这里的value2AllocBlocks、value2DefBlocks和value2UseBlocks改变了函数级别的分析信息
|
||||||
*/
|
*/
|
||||||
auto Mem2Reg::computeValue2Blocks() -> void {
|
auto Mem2Reg::computeValue2Blocks() -> void {
|
||||||
|
SysYPrinter printer(pModule); // 初始化打印机
|
||||||
|
std::cout << "===== Start computeValue2Blocks =====" << std::endl;
|
||||||
|
|
||||||
auto &functions = pModule->getFunctions();
|
auto &functions = pModule->getFunctions();
|
||||||
for (const auto &function : functions) {
|
for (const auto &function : functions) {
|
||||||
auto func = function.second.get();
|
auto func = function.second.get();
|
||||||
auto basicBlocks = func->getBasicBlocks();
|
std::cout << "\nProcessing function: " << func->getName() << std::endl;
|
||||||
|
|
||||||
FunctionAnalysisInfo* funcInfo = controlFlowAnalysis->getFunctionAnalysisInfo(func);
|
FunctionAnalysisInfo* funcInfo = controlFlowAnalysis->getFunctionAnalysisInfo(func);
|
||||||
|
if (!funcInfo) {
|
||||||
|
std::cerr << "ERROR: No analysis info for function " << func->getName() << std::endl;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto basicBlocks = func->getBasicBlocks();
|
||||||
|
std::cout << "BasicBlocks count: " << basicBlocks.size() << std::endl;
|
||||||
|
|
||||||
for (auto &it : basicBlocks) {
|
for (auto &it : basicBlocks) {
|
||||||
auto basicBlock = it.get();
|
auto basicBlock = it.get();
|
||||||
|
std::cout << "\nProcessing BB: " << basicBlock->getName() << std::endl;
|
||||||
|
// printer.printBlock(basicBlock); // 打印基本块内容
|
||||||
|
|
||||||
auto &instrs = basicBlock->getInstructions();
|
auto &instrs = basicBlock->getInstructions();
|
||||||
for (auto &instr : instrs) {
|
for (auto &instr : instrs) {
|
||||||
// 如果指令本身就是alloca指令,则加到allocblocks中
|
std::cout << " Analyzing instruction: ";
|
||||||
|
printer.printInst(instr.get());
|
||||||
|
std::cout << std::endl;
|
||||||
|
|
||||||
if (instr->isAlloca()) {
|
if (instr->isAlloca()) {
|
||||||
if (!(isArr(instr.get()) || isGlobal(instr.get()))) {
|
if (!(isArr(instr.get()) || isGlobal(instr.get()))) {
|
||||||
|
std::cout << " Found alloca: ";
|
||||||
|
printer.printInst(instr.get());
|
||||||
|
std::cout << " -> Adding to allocBlocks" << std::endl;
|
||||||
|
|
||||||
funcInfo->addValue2AllocBlocks(instr.get(), basicBlock);
|
funcInfo->addValue2AllocBlocks(instr.get(), basicBlock);
|
||||||
// func->addValue2AllocBlocks(instr.get(), basicBlock);
|
} else {
|
||||||
|
std::cout << " Skip array/global alloca: ";
|
||||||
|
printer.printInst(instr.get());
|
||||||
|
std::cout << std::endl;
|
||||||
}
|
}
|
||||||
} else if (instr->isStore()) {
|
}
|
||||||
// 否则就看Store指令,找到operands里的alloc指令
|
else if (instr->isStore()) {
|
||||||
auto val = instr->getOperand(1);
|
auto val = instr->getOperand(1);
|
||||||
|
std::cout << " Store target: ";
|
||||||
|
printer.printInst(dynamic_cast<Instruction *>(val));
|
||||||
|
|
||||||
if (!(isArr(val) || isGlobal(val))) {
|
if (!(isArr(val) || isGlobal(val))) {
|
||||||
funcInfo->addValue2DefBlocks(instr.get(), basicBlock);
|
std::cout << " Adding store to defBlocks for value: ";
|
||||||
// func->addValue2DefBlocks(val, basicBlock);
|
printer.printInst(dynamic_cast<Instruction *>(instr.get()));
|
||||||
|
std::cout << std::endl;
|
||||||
|
// 将store的目标值添加到defBlocks中
|
||||||
|
funcInfo->addValue2DefBlocks(val, basicBlock);
|
||||||
|
} else {
|
||||||
|
std::cout << " Skip array/global store" << std::endl;
|
||||||
}
|
}
|
||||||
} else if (instr->isLoad()) {
|
}
|
||||||
// 如果是load指令,那么就是use,看operand(因为IR是reg-reg型,所以use只看load就行)
|
else if (instr->isLoad()) {
|
||||||
auto val = instr->getOperand(0);
|
auto val = instr->getOperand(0);
|
||||||
|
std::cout << " Load source: ";
|
||||||
|
printer.printInst(dynamic_cast<Instruction *>(val));
|
||||||
|
std::cout << std::endl;
|
||||||
|
|
||||||
if (!(isArr(val) || isGlobal(val))) {
|
if (!(isArr(val) || isGlobal(val))) {
|
||||||
funcInfo->addValue2UseBlocks(instr.get(), basicBlock);
|
std::cout << " Adding load to useBlocks for value: ";
|
||||||
// func->addValue2UseBlocks(val, basicBlock);
|
printer.printInst(dynamic_cast<Instruction *>(val));
|
||||||
|
std::cout << std::endl;
|
||||||
|
|
||||||
|
funcInfo->addValue2UseBlocks(val, basicBlock);
|
||||||
|
} else {
|
||||||
|
std::cout << " Skip array/global load" << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 打印分析结果
|
||||||
|
std::cout << "\nAnalysis results for function " << func->getName() << ":" << std::endl;
|
||||||
|
|
||||||
|
auto &allocMap = funcInfo->getValue2AllocBlocks();
|
||||||
|
std::cout << "AllocBlocks (" << allocMap.size() << "):" << std::endl;
|
||||||
|
for (auto &[val, bb] : allocMap) {
|
||||||
|
std::cout << " ";
|
||||||
|
printer.printInst(dynamic_cast<Instruction *>(val));
|
||||||
|
std::cout << " in BB: " << bb->getName() << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto &defMap = funcInfo->getValue2DefBlocks();
|
||||||
|
std::cout << "DefBlocks (" << defMap.size() << "):" << std::endl;
|
||||||
|
for (auto &[val, bbs] : defMap) {
|
||||||
|
std::cout << " ";
|
||||||
|
printer.printInst(dynamic_cast<Instruction *>(val));
|
||||||
|
for (const auto &[bb, count] : bbs) {
|
||||||
|
std::cout << " in BB: " << bb->getName() << " (count: " << count << ")";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto &useMap = funcInfo->getValue2UseBlocks();
|
||||||
|
std::cout << "UseBlocks (" << useMap.size() << "):" << std::endl;
|
||||||
|
for (auto &[val, bbs] : useMap) {
|
||||||
|
std::cout << " ";
|
||||||
|
printer.printInst(dynamic_cast<Instruction *>(val));
|
||||||
|
for (const auto &[bb, count] : bbs) {
|
||||||
|
std::cout << " in BB: " << bb->getName() << " (count: " << count << ")";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
std::cout << "===== End computeValue2Blocks =====" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 级联关系的顺带消除,用于llvm mem2reg类预优化1
|
* @brief 级联关系的顺带消除,用于llvm mem2reg类预优化1
|
||||||
*
|
*
|
||||||
@@ -148,22 +222,80 @@ auto Mem2Reg::cascade(Instruction *instr, bool &changed, Function *func, BasicBl
|
|||||||
* @return 无返回值,但满足条件的情况下会对指令进行删除
|
* @return 无返回值,但满足条件的情况下会对指令进行删除
|
||||||
*/
|
*/
|
||||||
auto Mem2Reg::preOptimize1() -> void {
|
auto Mem2Reg::preOptimize1() -> void {
|
||||||
|
SysYPrinter printer(pModule); // 初始化打印机
|
||||||
|
|
||||||
auto &functions = pModule->getFunctions();
|
auto &functions = pModule->getFunctions();
|
||||||
|
std::cout << "===== Start preOptimize1 =====" << std::endl;
|
||||||
|
|
||||||
for (const auto &function : functions) {
|
for (const auto &function : functions) {
|
||||||
auto func = function.second.get();
|
auto func = function.second.get();
|
||||||
|
std::cout << "\nProcessing function: " << func->getName() << std::endl;
|
||||||
|
|
||||||
FunctionAnalysisInfo* funcInfo = controlFlowAnalysis->getFunctionAnalysisInfo(func);
|
FunctionAnalysisInfo* funcInfo = controlFlowAnalysis->getFunctionAnalysisInfo(func);
|
||||||
|
if (!funcInfo) {
|
||||||
|
std::cerr << "ERROR: No analysis info for function " << func->getName() << std::endl;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
auto &vToDefB = funcInfo->getValue2DefBlocks();
|
auto &vToDefB = funcInfo->getValue2DefBlocks();
|
||||||
auto &vToUseB = funcInfo->getValue2UseBlocks();
|
auto &vToUseB = funcInfo->getValue2UseBlocks();
|
||||||
// 先删除孤零零的alloca,即没有store的alloca
|
|
||||||
auto &vToAllocB = funcInfo->getValue2AllocBlocks();
|
auto &vToAllocB = funcInfo->getValue2AllocBlocks();
|
||||||
|
|
||||||
|
// 打印初始状态
|
||||||
|
std::cout << "Initial allocas: " << vToAllocB.size() << std::endl;
|
||||||
|
for (auto &[val, bb] : vToAllocB) {
|
||||||
|
std::cout << " Alloca: ";
|
||||||
|
printer.printInst(dynamic_cast<Instruction *>(val));
|
||||||
|
std::cout << " in BB: " << bb->getName() << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 阶段1:删除无store的alloca
|
||||||
|
std::cout << "\nPhase 1: Remove unused allocas" << std::endl;
|
||||||
for (auto iter = vToAllocB.begin(); iter != vToAllocB.end();) {
|
for (auto iter = vToAllocB.begin(); iter != vToAllocB.end();) {
|
||||||
auto val = iter->first;
|
auto val = iter->first;
|
||||||
|
auto bb = iter->second;
|
||||||
|
|
||||||
|
std::cout << "Checking alloca: ";
|
||||||
|
printer.printInst(dynamic_cast<Instruction *>(val));
|
||||||
|
std::cout << " in BB: " << bb->getName() << std::endl;
|
||||||
|
|
||||||
|
// 如果该alloca没有对应的store指令,且不在函数参数中
|
||||||
|
// 这里的vToDefB是value2DefBlocks,vToUseB是value2UseBlocks
|
||||||
|
|
||||||
|
// 打印vToDefB
|
||||||
|
std::cout << "DefBlocks (" << vToDefB.size() << "):" << std::endl;
|
||||||
|
for (auto &[val, bbs] : vToDefB) {
|
||||||
|
std::cout << " ";
|
||||||
|
printer.printInst(dynamic_cast<Instruction *>(val));
|
||||||
|
for (const auto &[bb, count] : bbs) {
|
||||||
|
std::cout << " in BB: " << bb->getName() << " (count: " << count << ")" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::cout << vToDefB.count(val) << std::endl;
|
||||||
|
bool hasStore = false;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (vToDefB.count(val) == 0U &&
|
if (vToDefB.count(val) == 0U &&
|
||||||
std::find(func->getEntryBlock()->getArguments().begin(), func->getEntryBlock()->getArguments().end(), val) ==
|
std::find(func->getEntryBlock()->getArguments().begin(),
|
||||||
func->getEntryBlock()->getArguments().end()) {
|
func->getEntryBlock()->getArguments().end(),
|
||||||
auto bb = iter->second;
|
val) == func->getEntryBlock()->getArguments().end()) {
|
||||||
auto tofind = std::find_if(bb->getInstructions().begin(), bb->getInstructions().end(),
|
|
||||||
[val](const auto &instr) { return instr.get() == val; });
|
std::cout << " Removing unused alloca: ";
|
||||||
|
printer.printInst(dynamic_cast<Instruction *>(val));
|
||||||
|
std::cout << std::endl;
|
||||||
|
|
||||||
|
auto tofind = std::find_if(bb->getInstructions().begin(),
|
||||||
|
bb->getInstructions().end(),
|
||||||
|
[val](const auto &instr) {
|
||||||
|
return instr.get() == val;
|
||||||
|
});
|
||||||
|
if (tofind == bb->getInstructions().end()) {
|
||||||
|
std::cerr << "ERROR: Alloca not found in BB!" << std::endl;
|
||||||
|
++iter;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
usedelete(tofind->get());
|
usedelete(tofind->get());
|
||||||
bb->getInstructions().erase(tofind);
|
bb->getInstructions().erase(tofind);
|
||||||
iter = vToAllocB.erase(iter);
|
iter = vToAllocB.erase(iter);
|
||||||
@@ -171,45 +303,83 @@ auto Mem2Reg::preOptimize1() -> void {
|
|||||||
++iter;
|
++iter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 阶段2:删除无load的store
|
||||||
|
std::cout << "\nPhase 2: Remove dead stores" << std::endl;
|
||||||
bool changed = true;
|
bool changed = true;
|
||||||
// 不动点法
|
int iteration = 0;
|
||||||
|
|
||||||
while (changed) {
|
while (changed) {
|
||||||
changed = false;
|
changed = false;
|
||||||
|
iteration++;
|
||||||
|
std::cout << "\nIteration " << iteration << std::endl;
|
||||||
|
|
||||||
for (auto iter = vToDefB.begin(); iter != vToDefB.end();) {
|
for (auto iter = vToDefB.begin(); iter != vToDefB.end();) {
|
||||||
auto val = iter->first;
|
auto val = iter->first;
|
||||||
// 找到没有load的变量,删除关于该变量的store
|
|
||||||
|
std::cout << "Checking value: ";
|
||||||
|
printer.printInst(dynamic_cast<Instruction *>(val));
|
||||||
|
std::cout << std::endl;
|
||||||
|
|
||||||
if (vToUseB.count(val) == 0U) {
|
if (vToUseB.count(val) == 0U) {
|
||||||
|
std::cout << " Found dead store for value: ";
|
||||||
|
printer.printInst(dynamic_cast<Instruction *>(val));
|
||||||
|
std::cout << std::endl;
|
||||||
|
|
||||||
auto blocks = funcInfo->getDefBlocksByValue(val);
|
auto blocks = funcInfo->getDefBlocksByValue(val);
|
||||||
for (auto block : blocks) {
|
for (auto block : blocks) {
|
||||||
|
std::cout << " Processing BB: " << block->getName() << std::endl;
|
||||||
|
// printer.printBlock(block); // 打印基本块内容
|
||||||
|
|
||||||
auto &instrs = block->getInstructions();
|
auto &instrs = block->getInstructions();
|
||||||
for (auto it = instrs.begin(); it != instrs.end();) {
|
for (auto it = instrs.begin(); it != instrs.end();) {
|
||||||
if (((*it)->isStore() && (*it)->getOperand(1) == val)) {
|
if ((*it)->isStore() && (*it)->getOperand(1) == val) {
|
||||||
// 关于该变量的store指令删除了,那对于之前的用于作store指令第0个操作数的那些指令就冗余了,也要删除
|
std::cout << " Removing store: ";
|
||||||
// 只考虑为指令,不考虑字面量和常数,因为它们与之前的指令无关了
|
printer.printInst(it->get());
|
||||||
// 同时考虑指令的话,该指令可能又与前面的指令可能有较强的级联关系,级联之间又有级联,因此又要考虑前面指令的删除
|
std::cout << std::endl;
|
||||||
|
|
||||||
auto valUsedByStore = dynamic_cast<Instruction *>((*it)->getOperand(0));
|
auto valUsedByStore = dynamic_cast<Instruction *>((*it)->getOperand(0));
|
||||||
usedelete(it->get());
|
usedelete(it->get());
|
||||||
// if it is constantvalue which it not instruction
|
|
||||||
if (valUsedByStore != nullptr && valUsedByStore->getUses().size() == 1 &&
|
if (valUsedByStore != nullptr &&
|
||||||
|
valUsedByStore->getUses().size() == 1 &&
|
||||||
valUsedByStore->getUses().front()->getUser() == (*it).get()) {
|
valUsedByStore->getUses().front()->getUser() == (*it).get()) {
|
||||||
|
std::cout << " Cascade deleting: ";
|
||||||
|
printer.printInst(valUsedByStore);
|
||||||
|
std::cout << std::endl;
|
||||||
|
|
||||||
cascade(valUsedByStore, changed, func, block, instrs);
|
cascade(valUsedByStore, changed, func, block, instrs);
|
||||||
}
|
}
|
||||||
it = instrs.erase(it);
|
it = instrs.erase(it);
|
||||||
|
changed = true;
|
||||||
} else {
|
} else {
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 再删除关于该变量的alloc(如果是函数参数的就不删除,函数参数的alloca在entry块的arguments内)
|
|
||||||
if (std::find(func->getEntryBlock()->getArguments().begin(), func->getEntryBlock()->getArguments().end(),
|
// 删除对应的alloca
|
||||||
|
if (std::find(func->getEntryBlock()->getArguments().begin(),
|
||||||
|
func->getEntryBlock()->getArguments().end(),
|
||||||
val) == func->getEntryBlock()->getArguments().end()) {
|
val) == func->getEntryBlock()->getArguments().end()) {
|
||||||
auto bb = funcInfo->getAllocBlockByValue(val);
|
auto bb = funcInfo->getAllocBlockByValue(val);
|
||||||
if (bb != nullptr) {
|
if (bb != nullptr) {
|
||||||
|
std::cout << " Removing alloca: ";
|
||||||
|
printer.printInst(dynamic_cast<Instruction *>(val));
|
||||||
|
std::cout << " in BB: " << bb->getName() << std::endl;
|
||||||
|
|
||||||
funcInfo->removeValue2AllocBlock(val);
|
funcInfo->removeValue2AllocBlock(val);
|
||||||
auto tofind = std::find_if(bb->getInstructions().begin(), bb->getInstructions().end(),
|
auto tofind = std::find_if(bb->getInstructions().begin(),
|
||||||
[val](const auto &instr) { return instr.get() == val; });
|
bb->getInstructions().end(),
|
||||||
usedelete(tofind->get());
|
[val](const auto &instr) {
|
||||||
bb->getInstructions().erase(tofind);
|
return instr.get() == val;
|
||||||
|
});
|
||||||
|
if (tofind != bb->getInstructions().end()) {
|
||||||
|
usedelete(tofind->get());
|
||||||
|
bb->getInstructions().erase(tofind);
|
||||||
|
} else {
|
||||||
|
std::cerr << "ERROR: Alloca not found in BB!" << std::endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
iter = vToDefB.erase(iter);
|
iter = vToDefB.erase(iter);
|
||||||
@@ -219,6 +389,7 @@ auto Mem2Reg::preOptimize1() -> void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
std::cout << "===== End preOptimize1 =====" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -584,18 +755,18 @@ auto Mem2Reg::mem2regPipeline() -> void {
|
|||||||
|
|
||||||
// 计算所有valueToBlocks的定义映射
|
// 计算所有valueToBlocks的定义映射
|
||||||
computeValue2Blocks();
|
computeValue2Blocks();
|
||||||
SysYPrinter printer(pModule);
|
// SysYPrinter printer(pModule);
|
||||||
// 参考llvm的mem2reg遍,在插入phi结点之前,先做些优化
|
// 参考llvm的mem2reg遍,在插入phi结点之前,先做些优化
|
||||||
preOptimize1();
|
preOptimize1();
|
||||||
printer.printIR();
|
// printer.printIR();
|
||||||
preOptimize2();
|
preOptimize2();
|
||||||
printer.printIR();
|
// printer.printIR();
|
||||||
// 优化三 可能会针对局部变量优化而删除整个块的alloca/store
|
// 优化三 可能会针对局部变量优化而删除整个块的alloca/store
|
||||||
preOptimize3();
|
preOptimize3();
|
||||||
//再进行活跃变量分析
|
//再进行活跃变量分析
|
||||||
// 报错?
|
// 报错?
|
||||||
|
|
||||||
printer.printIR();
|
// printer.printIR();
|
||||||
dataFlowAnalysisUtils.backwardAnalyze(pModule);
|
dataFlowAnalysisUtils.backwardAnalyze(pModule);
|
||||||
// 为所有变量插入phi结点
|
// 为所有变量插入phi结点
|
||||||
insertPhi();
|
insertPhi();
|
||||||
|
|||||||
@@ -264,7 +264,7 @@ std::any SysYIRGenerator::visitAssignStmt(SysYParser::AssignStmtContext *ctx) {
|
|||||||
dims.push_back(std::any_cast<Value *>(visitExp(exp)));
|
dims.push_back(std::any_cast<Value *>(visitExp(exp)));
|
||||||
}
|
}
|
||||||
|
|
||||||
User* variable = module->getVariable(name);
|
auto variable = module->getVariable(name);
|
||||||
Value* value = std::any_cast<Value *>(visitExp(ctx->exp()));
|
Value* value = std::any_cast<Value *>(visitExp(ctx->exp()));
|
||||||
Type* variableType = dynamic_cast<PointerType *>(variable->getType())->getBaseType();
|
Type* variableType = dynamic_cast<PointerType *>(variable->getType())->getBaseType();
|
||||||
|
|
||||||
|
|||||||
@@ -438,14 +438,16 @@ void SysYPrinter::printInst(Instruction *pInst) {
|
|||||||
|
|
||||||
case Kind::kPhi: {
|
case Kind::kPhi: {
|
||||||
auto phiInst = dynamic_cast<PhiInst *>(pInst);
|
auto phiInst = dynamic_cast<PhiInst *>(pInst);
|
||||||
std::cout << "%" << phiInst->getName() << " = phi ";
|
std::cout << "%";
|
||||||
|
printValue(phiInst->getOperand(0));
|
||||||
|
std::cout << " = phi ";
|
||||||
printType(phiInst->getType());
|
printType(phiInst->getType());
|
||||||
|
|
||||||
for (unsigned i = 0; i < phiInst->getNumOperands(); i += 2) {
|
for (unsigned i = 1; i < phiInst->getNumOperands(); i++) {
|
||||||
if (i > 0) std::cout << ", ";
|
if (i > 0) std::cout << ", ";
|
||||||
std::cout << "[ ";
|
std::cout << "[ ";
|
||||||
printValue(phiInst->getOperand(i));
|
printValue(phiInst->getOperand(i));
|
||||||
std::cout << ", %" << dynamic_cast<BasicBlock*>(phiInst->getOperand(i+1))->getName() << " ]";
|
std::cout << " ]";
|
||||||
}
|
}
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
} break;
|
} break;
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ public:
|
|||||||
std::set<Function*> callees; ///< 函数调用集合
|
std::set<Function*> callees; ///< 函数调用集合
|
||||||
Loop_list loops; ///< 所有循环
|
Loop_list loops; ///< 所有循环
|
||||||
Loop_list topLoops; ///< 顶层循环
|
Loop_list topLoops; ///< 顶层循环
|
||||||
block_loop_map basicblock2Loop; ///< 基本块到循环映射
|
// block_loop_map basicblock2Loop; ///< 基本块到循环映射
|
||||||
std::list<std::unique_ptr<AllocaInst>> indirectAllocas; ///< 间接分配内存
|
std::list<std::unique_ptr<AllocaInst>> indirectAllocas; ///< 间接分配内存
|
||||||
|
|
||||||
// 值定义/使用信息
|
// 值定义/使用信息
|
||||||
@@ -198,7 +198,7 @@ public:
|
|||||||
callees.clear();
|
callees.clear();
|
||||||
loops.clear();
|
loops.clear();
|
||||||
topLoops.clear();
|
topLoops.clear();
|
||||||
basicblock2Loop.clear();
|
// basicblock2Loop.clear();
|
||||||
indirectAllocas.clear();
|
indirectAllocas.clear();
|
||||||
value2AllocBlocks.clear();
|
value2AllocBlocks.clear();
|
||||||
value2DefBlocks.clear();
|
value2DefBlocks.clear();
|
||||||
|
|||||||
Reference in New Issue
Block a user