[SysYIROptUtils]增加通用优化工具类,修改相关代码
This commit is contained in:
@ -37,7 +37,7 @@ void DeadCodeElimination::eliminateDeadStores(Function* func, bool& changed) {
|
|||||||
auto storeInst = dynamic_cast<StoreInst*>(inst);
|
auto storeInst = dynamic_cast<StoreInst*>(inst);
|
||||||
auto pointer = storeInst->getPointer();
|
auto pointer = storeInst->getPointer();
|
||||||
// 如果是全局变量或者是函数的数组参数
|
// 如果是全局变量或者是函数的数组参数
|
||||||
if (isGlobal(pointer) || (isArr(pointer) &&
|
if (SysYIROptUtils::isGlobal(pointer) || (SysYIROptUtils::isArr(pointer) &&
|
||||||
std::find(func->getEntryBlock()->getArguments().begin(),
|
std::find(func->getEntryBlock()->getArguments().begin(),
|
||||||
func->getEntryBlock()->getArguments().end(),
|
func->getEntryBlock()->getArguments().end(),
|
||||||
pointer) != func->getEntryBlock()->getArguments().end())) {
|
pointer) != func->getEntryBlock()->getArguments().end())) {
|
||||||
@ -63,7 +63,7 @@ void DeadCodeElimination::eliminateDeadStores(Function* func, bool& changed) {
|
|||||||
std::cout << "=== Dead Store Found ===\n";
|
std::cout << "=== Dead Store Found ===\n";
|
||||||
SysYPrinter::printInst(storeInst);
|
SysYPrinter::printInst(storeInst);
|
||||||
}
|
}
|
||||||
usedelete(storeInst);
|
SysYIROptUtils::usedelete(storeInst);
|
||||||
iter = instrs.erase(iter);
|
iter = instrs.erase(iter);
|
||||||
} else {
|
} else {
|
||||||
++iter;
|
++iter;
|
||||||
@ -85,7 +85,7 @@ void DeadCodeElimination::eliminateDeadLoads(Function* func, bool& changed) {
|
|||||||
std::cout << "=== Dead Load Binary Unary Found ===\n";
|
std::cout << "=== Dead Load Binary Unary Found ===\n";
|
||||||
SysYPrinter::printInst(inst);
|
SysYPrinter::printInst(inst);
|
||||||
}
|
}
|
||||||
usedelete(inst);
|
SysYIROptUtils::usedelete(inst);
|
||||||
iter = instrs.erase(iter);
|
iter = instrs.erase(iter);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -114,7 +114,7 @@ void DeadCodeElimination::eliminateDeadAllocas(Function* func, bool& changed) {
|
|||||||
std::cout << "=== Dead Alloca Found ===\n";
|
std::cout << "=== Dead Alloca Found ===\n";
|
||||||
SysYPrinter::printInst(inst);
|
SysYPrinter::printInst(inst);
|
||||||
}
|
}
|
||||||
usedelete(inst);
|
SysYIROptUtils::usedelete(inst);
|
||||||
iter = instrs.erase(iter);
|
iter = instrs.erase(iter);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -183,7 +183,7 @@ void DeadCodeElimination::eliminateDeadRedundantLoadStore(Function* func, bool&
|
|||||||
/// 如果 pointer 仅被该 phi 使用,可以删除 ph
|
/// 如果 pointer 仅被该 phi 使用,可以删除 ph
|
||||||
if (tag) {
|
if (tag) {
|
||||||
changed = true;
|
changed = true;
|
||||||
usedelete(inst);
|
SysYIROptUtils::usedelete(inst);
|
||||||
iter = instrs.erase(iter);
|
iter = instrs.erase(iter);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -193,7 +193,7 @@ void DeadCodeElimination::eliminateDeadRedundantLoadStore(Function* func, bool&
|
|||||||
auto pointer = memsetInst->getPointer();
|
auto pointer = memsetInst->getPointer();
|
||||||
if (pointer->getUses().empty()) {
|
if (pointer->getUses().empty()) {
|
||||||
changed = true;
|
changed = true;
|
||||||
usedelete(inst);
|
SysYIROptUtils::usedelete(inst);
|
||||||
iter = instrs.erase(iter);
|
iter = instrs.erase(iter);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -234,7 +234,7 @@ void DeadCodeElimination::eliminateDeadRedundantLoadStore(Function* func, bool&
|
|||||||
SysYPrinter::printInst(loadInst);
|
SysYPrinter::printInst(loadInst);
|
||||||
SysYPrinter::printInst(nextStore);
|
SysYPrinter::printInst(nextStore);
|
||||||
}
|
}
|
||||||
usedelete(loadInst);
|
SysYIROptUtils::usedelete(loadInst);
|
||||||
iter = instrs.erase(iter);
|
iter = instrs.erase(iter);
|
||||||
// 删除 prevStore 这里是不是可以留给删除无用store处理?
|
// 删除 prevStore 这里是不是可以留给删除无用store处理?
|
||||||
// if (prevStore->getUses().empty()) {
|
// if (prevStore->getUses().empty()) {
|
||||||
@ -256,21 +256,4 @@ void DeadCodeElimination::eliminateDeadRedundantLoadStore(Function* func, bool&
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool DeadCodeElimination::isGlobal(Value *val){
|
|
||||||
auto gval = dynamic_cast<GlobalValue *>(val);
|
|
||||||
return gval != nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DeadCodeElimination::isArr(Value *val){
|
|
||||||
auto aval = dynamic_cast<AllocaInst *>(val);
|
|
||||||
return aval != nullptr && aval->getNumDims() != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DeadCodeElimination::usedelete(Instruction *instr){
|
|
||||||
for (auto &use1 : instr->getOperands()) {
|
|
||||||
auto val1 = use1->getValue();
|
|
||||||
val1->removeUse(use1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace sysy
|
} // namespace sysy
|
||||||
@ -75,7 +75,7 @@ auto Mem2Reg::computeValue2Blocks() -> void {
|
|||||||
// std::cout << std::endl;
|
// std::cout << std::endl;
|
||||||
|
|
||||||
if (instr->isAlloca()) {
|
if (instr->isAlloca()) {
|
||||||
if (!(isArr(instr.get()) || isGlobal(instr.get()))) {
|
if (!(SysYIROptUtils::isArr(instr.get()) || SysYIROptUtils::isGlobal(instr.get()))) {
|
||||||
// std::cout << " Found alloca: ";
|
// std::cout << " Found alloca: ";
|
||||||
// printer.printInst(instr.get());
|
// printer.printInst(instr.get());
|
||||||
// std::cout << " -> Adding to allocBlocks" << std::endl;
|
// std::cout << " -> Adding to allocBlocks" << std::endl;
|
||||||
@ -92,7 +92,7 @@ auto Mem2Reg::computeValue2Blocks() -> void {
|
|||||||
// std::cout << " Store target: ";
|
// std::cout << " Store target: ";
|
||||||
// printer.printInst(dynamic_cast<Instruction *>(val));
|
// printer.printInst(dynamic_cast<Instruction *>(val));
|
||||||
|
|
||||||
if (!(isArr(val) || isGlobal(val))) {
|
if (!(SysYIROptUtils::isArr(val) || SysYIROptUtils::isGlobal(val))) {
|
||||||
// std::cout << " Adding store to defBlocks for value: ";
|
// std::cout << " Adding store to defBlocks for value: ";
|
||||||
// printer.printInst(dynamic_cast<Instruction *>(instr.get()));
|
// printer.printInst(dynamic_cast<Instruction *>(instr.get()));
|
||||||
// std::cout << std::endl;
|
// std::cout << std::endl;
|
||||||
@ -108,7 +108,7 @@ auto Mem2Reg::computeValue2Blocks() -> void {
|
|||||||
// printer.printInst(dynamic_cast<Instruction *>(val));
|
// printer.printInst(dynamic_cast<Instruction *>(val));
|
||||||
// std::cout << std::endl;
|
// std::cout << std::endl;
|
||||||
|
|
||||||
if (!(isArr(val) || isGlobal(val))) {
|
if (!(SysYIROptUtils::isArr(val) || SysYIROptUtils::isGlobal(val))) {
|
||||||
// std::cout << " Adding load to useBlocks for value: ";
|
// std::cout << " Adding load to useBlocks for value: ";
|
||||||
// printer.printInst(dynamic_cast<Instruction *>(val));
|
// printer.printInst(dynamic_cast<Instruction *>(val));
|
||||||
// std::cout << std::endl;
|
// std::cout << std::endl;
|
||||||
@ -199,7 +199,7 @@ auto Mem2Reg::cascade(Instruction *instr, bool &changed, Function *func, BasicBl
|
|||||||
auto tofind =
|
auto tofind =
|
||||||
std::find_if(instrs.begin(), instrs.end(), [&top](const auto &instr) { return instr.get() == top; });
|
std::find_if(instrs.begin(), instrs.end(), [&top](const auto &instr) { return instr.get() == top; });
|
||||||
assert(tofind != instrs.end());
|
assert(tofind != instrs.end());
|
||||||
usedelete(tofind->get());
|
SysYIROptUtils::usedelete(tofind->get());
|
||||||
instrs.erase(tofind);
|
instrs.erase(tofind);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -291,7 +291,7 @@ auto Mem2Reg::preOptimize1() -> void {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
usedelete(tofind->get());
|
SysYIROptUtils::usedelete(tofind->get());
|
||||||
bb->getInstructions().erase(tofind);
|
bb->getInstructions().erase(tofind);
|
||||||
iter = vToAllocB.erase(iter);
|
iter = vToAllocB.erase(iter);
|
||||||
} else {
|
} else {
|
||||||
@ -334,7 +334,7 @@ auto Mem2Reg::preOptimize1() -> void {
|
|||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
|
||||||
auto valUsedByStore = dynamic_cast<Instruction *>((*it)->getOperand(0));
|
auto valUsedByStore = dynamic_cast<Instruction *>((*it)->getOperand(0));
|
||||||
usedelete(it->get());
|
SysYIROptUtils::usedelete(it->get());
|
||||||
|
|
||||||
if (valUsedByStore != nullptr &&
|
if (valUsedByStore != nullptr &&
|
||||||
valUsedByStore->getUses().size() == 1 &&
|
valUsedByStore->getUses().size() == 1 &&
|
||||||
@ -370,7 +370,7 @@ auto Mem2Reg::preOptimize1() -> void {
|
|||||||
return instr.get() == val;
|
return instr.get() == val;
|
||||||
});
|
});
|
||||||
if (tofind != bb->getInstructions().end()) {
|
if (tofind != bb->getInstructions().end()) {
|
||||||
usedelete(tofind->get());
|
SysYIROptUtils::usedelete(tofind->get());
|
||||||
bb->getInstructions().erase(tofind);
|
bb->getInstructions().erase(tofind);
|
||||||
} else {
|
} else {
|
||||||
std::cerr << "ERROR: Alloca not found in BB!" << std::endl;
|
std::cerr << "ERROR: Alloca not found in BB!" << std::endl;
|
||||||
@ -423,7 +423,7 @@ auto Mem2Reg::preOptimize2() -> void {
|
|||||||
for (auto curit = std::next(it); curit != instrs.end();) {
|
for (auto curit = std::next(it); curit != instrs.end();) {
|
||||||
if ((*curit)->isLoad() && (*curit)->getOperand(0) == val) {
|
if ((*curit)->isLoad() && (*curit)->getOperand(0) == val) {
|
||||||
curit->get()->replaceAllUsesWith(propogationVal);
|
curit->get()->replaceAllUsesWith(propogationVal);
|
||||||
usedelete(curit->get());
|
SysYIROptUtils::usedelete(curit->get());
|
||||||
curit = instrs.erase(curit);
|
curit = instrs.erase(curit);
|
||||||
funcInfo->removeValue2UseBlock(val, block);
|
funcInfo->removeValue2UseBlock(val, block);
|
||||||
} else {
|
} else {
|
||||||
@ -454,7 +454,7 @@ auto Mem2Reg::preOptimize2() -> void {
|
|||||||
for (auto childIter = childInstrs.begin(); childIter != childInstrs.end();) {
|
for (auto childIter = childInstrs.begin(); childIter != childInstrs.end();) {
|
||||||
if ((*childIter)->isLoad() && (*childIter)->getOperand(0) == val) {
|
if ((*childIter)->isLoad() && (*childIter)->getOperand(0) == val) {
|
||||||
childIter->get()->replaceAllUsesWith(propogationVal);
|
childIter->get()->replaceAllUsesWith(propogationVal);
|
||||||
usedelete(childIter->get());
|
SysYIROptUtils::usedelete(childIter->get());
|
||||||
childIter = childInstrs.erase(childIter);
|
childIter = childInstrs.erase(childIter);
|
||||||
funcInfo->removeValue2UseBlock(val, child);
|
funcInfo->removeValue2UseBlock(val, child);
|
||||||
} else {
|
} else {
|
||||||
@ -465,7 +465,7 @@ auto Mem2Reg::preOptimize2() -> void {
|
|||||||
// 如果对该val的所有load均替换掉了,那么对于该val的defining block中的最后一个define也可以删除了
|
// 如果对该val的所有load均替换掉了,那么对于该val的defining block中的最后一个define也可以删除了
|
||||||
// 同时该块中前面对于该val的define也变成死代码了,可调用preOptimize1进行删除
|
// 同时该块中前面对于该val的define也变成死代码了,可调用preOptimize1进行删除
|
||||||
if (funcInfo->getUseBlocksByValue(val).empty()) {
|
if (funcInfo->getUseBlocksByValue(val).empty()) {
|
||||||
usedelete(it->get());
|
SysYIROptUtils::usedelete(it->get());
|
||||||
instrs.erase(it);
|
instrs.erase(it);
|
||||||
auto change = funcInfo->removeValue2DefBlock(val, block);
|
auto change = funcInfo->removeValue2DefBlock(val, block);
|
||||||
if (change) {
|
if (change) {
|
||||||
@ -476,7 +476,7 @@ auto Mem2Reg::preOptimize2() -> void {
|
|||||||
assert(bb != nullptr);
|
assert(bb != nullptr);
|
||||||
auto tofind = std::find_if(bb->getInstructions().begin(), bb->getInstructions().end(),
|
auto tofind = std::find_if(bb->getInstructions().begin(), bb->getInstructions().end(),
|
||||||
[val](const auto &instr) { return instr.get() == val; });
|
[val](const auto &instr) { return instr.get() == val; });
|
||||||
usedelete(tofind->get());
|
SysYIROptUtils::usedelete(tofind->get());
|
||||||
bb->getInstructions().erase(tofind);
|
bb->getInstructions().erase(tofind);
|
||||||
funcInfo->removeValue2AllocBlock(val);
|
funcInfo->removeValue2AllocBlock(val);
|
||||||
}
|
}
|
||||||
@ -529,7 +529,7 @@ auto Mem2Reg::preOptimize3() -> void {
|
|||||||
for (auto curit = std::next(it); curit != last;) {
|
for (auto curit = std::next(it); curit != last;) {
|
||||||
if ((*curit)->isLoad() && (*curit)->getOperand(0) == val) {
|
if ((*curit)->isLoad() && (*curit)->getOperand(0) == val) {
|
||||||
curit->get()->replaceAllUsesWith(propogationVal);
|
curit->get()->replaceAllUsesWith(propogationVal);
|
||||||
usedelete(curit->get());
|
SysYIROptUtils::usedelete(curit->get());
|
||||||
curit = instrs.erase(curit);
|
curit = instrs.erase(curit);
|
||||||
funcInfo->removeValue2UseBlock(val, block);
|
funcInfo->removeValue2UseBlock(val, block);
|
||||||
} else {
|
} else {
|
||||||
@ -541,14 +541,14 @@ auto Mem2Reg::preOptimize3() -> void {
|
|||||||
[val](const auto &instr) { return instr == val; }) !=
|
[val](const auto &instr) { return instr == val; }) !=
|
||||||
func->getEntryBlock()->getArguments().end()) &&
|
func->getEntryBlock()->getArguments().end()) &&
|
||||||
last == instrs.end()) {
|
last == instrs.end()) {
|
||||||
usedelete(it->get());
|
SysYIROptUtils::usedelete(it->get());
|
||||||
it = instrs.erase(it);
|
it = instrs.erase(it);
|
||||||
if (funcInfo->removeValue2DefBlock(val, block)) {
|
if (funcInfo->removeValue2DefBlock(val, block)) {
|
||||||
auto bb = funcInfo->getAllocBlockByValue(val);
|
auto bb = funcInfo->getAllocBlockByValue(val);
|
||||||
if (bb != nullptr) {
|
if (bb != nullptr) {
|
||||||
auto tofind = std::find_if(bb->getInstructions().begin(), bb->getInstructions().end(),
|
auto tofind = std::find_if(bb->getInstructions().begin(), bb->getInstructions().end(),
|
||||||
[val](const auto &instr) { return instr.get() == val; });
|
[val](const auto &instr) { return instr.get() == val; });
|
||||||
usedelete(tofind->get());
|
SysYIROptUtils::usedelete(tofind->get());
|
||||||
bb->getInstructions().erase(tofind);
|
bb->getInstructions().erase(tofind);
|
||||||
funcInfo->removeValue2AllocBlock(val);
|
funcInfo->removeValue2AllocBlock(val);
|
||||||
}
|
}
|
||||||
@ -610,7 +610,7 @@ auto Mem2Reg::rename(BasicBlock *block, std::unordered_map<Value *, int> &count,
|
|||||||
// 对于load指令,变量用最新的那个
|
// 对于load指令,变量用最新的那个
|
||||||
if (instr->isLoad()) {
|
if (instr->isLoad()) {
|
||||||
auto val = instr->getOperand(0);
|
auto val = instr->getOperand(0);
|
||||||
if (!(isArr(val) || isGlobal(val))) {
|
if (!(SysYIROptUtils::isArr(val) || SysYIROptUtils::isGlobal(val))) {
|
||||||
if (!stacks[val].empty()) {
|
if (!stacks[val].empty()) {
|
||||||
instr->replaceOperand(0, stacks[val].top());
|
instr->replaceOperand(0, stacks[val].top());
|
||||||
}
|
}
|
||||||
@ -621,7 +621,7 @@ auto Mem2Reg::rename(BasicBlock *block, std::unordered_map<Value *, int> &count,
|
|||||||
if (instr->isAlloca()) {
|
if (instr->isAlloca()) {
|
||||||
// alloca指令名字不改了,命名就按x,x_1,x_2...来就行
|
// alloca指令名字不改了,命名就按x,x_1,x_2...来就行
|
||||||
auto val = instr;
|
auto val = instr;
|
||||||
if (!(isArr(val) || isGlobal(val))) {
|
if (!(SysYIROptUtils::isArr(val) || SysYIROptUtils::isGlobal(val))) {
|
||||||
++valPop[val];
|
++valPop[val];
|
||||||
stacks[val].push(val);
|
stacks[val].push(val);
|
||||||
++count[val];
|
++count[val];
|
||||||
@ -629,11 +629,11 @@ auto Mem2Reg::rename(BasicBlock *block, std::unordered_map<Value *, int> &count,
|
|||||||
} else if (instr->isPhi()) {
|
} else if (instr->isPhi()) {
|
||||||
// Phi指令也是一条特殊的define指令
|
// Phi指令也是一条特殊的define指令
|
||||||
auto val = dynamic_cast<PhiInst *>(instr)->getMapVal();
|
auto val = dynamic_cast<PhiInst *>(instr)->getMapVal();
|
||||||
if (!(isArr(val) || isGlobal(val))) {
|
if (!(SysYIROptUtils::isArr(val) || SysYIROptUtils::isGlobal(val))) {
|
||||||
auto i = count[val];
|
auto i = count[val];
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
// 对还未alloca就有phi的指令的处理,直接删除
|
// 对还未alloca就有phi的指令的处理,直接删除
|
||||||
usedelete(iter->get());
|
SysYIROptUtils::usedelete(iter->get());
|
||||||
iter = instrs.erase(iter);
|
iter = instrs.erase(iter);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -649,7 +649,7 @@ auto Mem2Reg::rename(BasicBlock *block, std::unordered_map<Value *, int> &count,
|
|||||||
} else {
|
} else {
|
||||||
// store指令看operand的名字,我们的实现是规定变量在operand的第二位,用一个新的alloca x_i代替
|
// store指令看operand的名字,我们的实现是规定变量在operand的第二位,用一个新的alloca x_i代替
|
||||||
auto val = instr->getOperand(1);
|
auto val = instr->getOperand(1);
|
||||||
if (!(isArr(val) || isGlobal(val))) {
|
if (!(SysYIROptUtils::isArr(val) || SysYIROptUtils::isGlobal(val))) {
|
||||||
auto i = count[val];
|
auto i = count[val];
|
||||||
auto newname = dynamic_cast<Instruction *>(val)->getName() + "_" + std::to_string(i);
|
auto newname = dynamic_cast<Instruction *>(val)->getName() + "_" + std::to_string(i);
|
||||||
auto newalloca = pBuilder->createAllocaInstWithoutInsert(val->getType(), {}, block, newname);
|
auto newalloca = pBuilder->createAllocaInstWithoutInsert(val->getType(), {}, block, newname);
|
||||||
@ -773,29 +773,4 @@ auto Mem2Reg::getPredIndex(BasicBlock *n, BasicBlock *s) -> int {
|
|||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 判断一个value是不是全局变量
|
|
||||||
*/
|
|
||||||
auto Mem2Reg::isGlobal(Value *val) -> bool {
|
|
||||||
auto gval = dynamic_cast<GlobalValue *>(val);
|
|
||||||
return gval != nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 判断一个value是不是数组
|
|
||||||
*/
|
|
||||||
auto Mem2Reg::isArr(Value *val) -> bool {
|
|
||||||
auto aval = dynamic_cast<AllocaInst *>(val);
|
|
||||||
return aval != nullptr && aval->getNumDims() != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除一个指令的operand对应的value的该条use
|
|
||||||
*/
|
|
||||||
auto Mem2Reg::usedelete(Instruction *instr) -> void {
|
|
||||||
for (auto &use : instr->getOperands()) {
|
|
||||||
auto val = use->getValue();
|
|
||||||
val->removeUse(use);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} // namespace sysy
|
} // namespace sysy
|
||||||
|
|||||||
@ -103,7 +103,7 @@ void Reg2Mem::DeletePhiInst(){
|
|||||||
}
|
}
|
||||||
// 删除phi指令
|
// 删除phi指令
|
||||||
auto &instructions = basicBlock->getInstructions();
|
auto &instructions = basicBlock->getInstructions();
|
||||||
usedelete(iter->get());
|
SysYIROptUtils::usedelete(iter->get());
|
||||||
iter = instructions.erase(iter);
|
iter = instructions.erase(iter);
|
||||||
if (basicBlock->getNumInstructions() == 0) {
|
if (basicBlock->getNumInstructions() == 0) {
|
||||||
if (basicBlock->getNumSuccessors() == 1) {
|
if (basicBlock->getNumSuccessors() == 1) {
|
||||||
@ -119,11 +119,4 @@ void Reg2Mem::DeletePhiInst(){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reg2Mem::usedelete(Instruction *instr) {
|
|
||||||
for (auto &use : instr->getOperands()) {
|
|
||||||
auto val = use->getValue();
|
|
||||||
val->removeUse(use);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace sysy
|
} // namespace sysy
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
#include "SysYIROptPre.h"
|
#include "SysYIROptPre.h"
|
||||||
|
#include "SysYIROptUtils.h"
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <map>
|
#include <map>
|
||||||
@ -10,18 +11,6 @@
|
|||||||
|
|
||||||
namespace sysy {
|
namespace sysy {
|
||||||
|
|
||||||
/**
|
|
||||||
* use删除operand,以免扰乱后续分析
|
|
||||||
* instr: 要删除的指令
|
|
||||||
*/
|
|
||||||
void SysYOptPre::usedelete(Instruction *instr) {
|
|
||||||
for (auto &use : instr->getOperands()) {
|
|
||||||
Value* val = use->getValue();
|
|
||||||
// std::cout << delete << val->getName() << std::endl;
|
|
||||||
val->removeUse(use);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// 删除br后的无用指令
|
// 删除br后的无用指令
|
||||||
void SysYOptPre::SysYDelInstAfterBr() {
|
void SysYOptPre::SysYDelInstAfterBr() {
|
||||||
@ -34,7 +23,7 @@ void SysYOptPre::SysYDelInstAfterBr() {
|
|||||||
auto Branchiter = instructions.end();
|
auto Branchiter = instructions.end();
|
||||||
for (auto iter = instructions.begin(); iter != instructions.end(); ++iter) {
|
for (auto iter = instructions.begin(); iter != instructions.end(); ++iter) {
|
||||||
if (Branch)
|
if (Branch)
|
||||||
usedelete(iter->get());
|
SysYIROptUtils::usedelete(iter->get());
|
||||||
else if ((*iter)->isTerminator()){
|
else if ((*iter)->isTerminator()){
|
||||||
Branch = true;
|
Branch = true;
|
||||||
Branchiter = iter;
|
Branchiter = iter;
|
||||||
@ -69,7 +58,7 @@ void SysYOptPre::SysYDelInstAfterBr() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 合并空基本块
|
||||||
void SysYOptPre::SysYBlockMerge() {
|
void SysYOptPre::SysYBlockMerge() {
|
||||||
auto &functions = pModule->getFunctions(); //std::map<std::string, std::unique_ptr<Function>>
|
auto &functions = pModule->getFunctions(); //std::map<std::string, std::unique_ptr<Function>>
|
||||||
for (auto &function : functions) {
|
for (auto &function : functions) {
|
||||||
@ -91,12 +80,12 @@ void SysYOptPre::SysYBlockMerge() {
|
|||||||
auto thelastinstinst = block->end();
|
auto thelastinstinst = block->end();
|
||||||
(--thelastinstinst);
|
(--thelastinstinst);
|
||||||
if (thelastinstinst->get()->isUnconditional()) {
|
if (thelastinstinst->get()->isUnconditional()) {
|
||||||
usedelete(thelastinstinst->get());
|
SysYIROptUtils::usedelete(thelastinstinst->get());
|
||||||
block->getInstructions().erase(thelastinstinst);
|
block->getInstructions().erase(thelastinstinst);
|
||||||
} else if (thelastinstinst->get()->isConditional()) {
|
} else if (thelastinstinst->get()->isConditional()) {
|
||||||
// 如果是条件分支,判断条件是否相同,主要优化相同布尔表达式
|
// 如果是条件分支,判断条件是否相同,主要优化相同布尔表达式
|
||||||
if (thelastinstinst->get()->getOperand(1)->getName() == thelastinstinst->get()->getOperand(1)->getName()) {
|
if (thelastinstinst->get()->getOperand(1)->getName() == thelastinstinst->get()->getOperand(1)->getName()) {
|
||||||
usedelete(thelastinstinst->get());
|
SysYIROptUtils::usedelete(thelastinstinst->get());
|
||||||
block->getInstructions().erase(thelastinstinst);
|
block->getInstructions().erase(thelastinstinst);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -170,7 +159,7 @@ void SysYOptPre::SysYDelNoPreBLock() {
|
|||||||
|
|
||||||
if (!blockIter->get()->getreachable())
|
if (!blockIter->get()->getreachable())
|
||||||
for (auto &iterInst : blockIter->get()->getInstructions())
|
for (auto &iterInst : blockIter->get()->getInstructions())
|
||||||
usedelete(iterInst.get());
|
SysYIROptUtils::usedelete(iterInst.get());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -303,7 +292,7 @@ void SysYOptPre::SysYDelEmptyBlock() {
|
|||||||
if (dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1)) ==
|
if (dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1)) ==
|
||||||
dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2))) {
|
dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2))) {
|
||||||
auto thebrBlock = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1));
|
auto thebrBlock = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1));
|
||||||
usedelete(thelastinst->get());
|
SysYIROptUtils::usedelete(thelastinst->get());
|
||||||
thelastinst = basicBlock->getInstructions().erase(thelastinst);
|
thelastinst = basicBlock->getInstructions().erase(thelastinst);
|
||||||
pBuilder->setPosition(basicBlock.get(), basicBlock->end());
|
pBuilder->setPosition(basicBlock.get(), basicBlock->end());
|
||||||
pBuilder->createUncondBrInst(thebrBlock, {});
|
pBuilder->createUncondBrInst(thebrBlock, {});
|
||||||
@ -344,7 +333,7 @@ void SysYOptPre::SysYDelEmptyBlock() {
|
|||||||
if (dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1)) ==
|
if (dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1)) ==
|
||||||
dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2))) {
|
dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2))) {
|
||||||
auto thebrBlock = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1));
|
auto thebrBlock = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1));
|
||||||
usedelete(thelastinst->get());
|
SysYIROptUtils::usedelete(thelastinst->get());
|
||||||
thelastinst = basicBlock->getInstructions().erase(thelastinst);
|
thelastinst = basicBlock->getInstructions().erase(thelastinst);
|
||||||
pBuilder->setPosition(basicBlock.get(), basicBlock->end());
|
pBuilder->setPosition(basicBlock.get(), basicBlock->end());
|
||||||
pBuilder->createUncondBrInst(thebrBlock, {});
|
pBuilder->createUncondBrInst(thebrBlock, {});
|
||||||
@ -420,7 +409,7 @@ void SysYOptPre::SysYDelEmptyBlock() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (auto &iterInst : iter->get()->getInstructions())
|
for (auto &iterInst : iter->get()->getInstructions())
|
||||||
usedelete(iterInst.get());
|
SysYIROptUtils::usedelete(iterInst.get());
|
||||||
// 删除不可达基本块的phi指令的操作数
|
// 删除不可达基本块的phi指令的操作数
|
||||||
for (auto &succ : iter->get()->getSuccessors()) {
|
for (auto &succ : iter->get()->getSuccessors()) {
|
||||||
int index = 0;
|
int index = 0;
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
#include "IR.h"
|
#include "IR.h"
|
||||||
#include "SysYIRAnalyser.h"
|
#include "SysYIRAnalyser.h"
|
||||||
#include "SysYIRPrinter.h"
|
#include "SysYIRPrinter.h"
|
||||||
|
#include "SysYIROptUtils.h"
|
||||||
|
|
||||||
namespace sysy {
|
namespace sysy {
|
||||||
|
|
||||||
@ -31,9 +32,5 @@ class DeadCodeElimination {
|
|||||||
void eliminateDeadGlobals(bool& changed); // 消除无用全局变量
|
void eliminateDeadGlobals(bool& changed); // 消除无用全局变量
|
||||||
void eliminateDeadIndirectiveAllocas(Function* func, bool& changed); // 消除无用间接内存分配(phi节点)
|
void eliminateDeadIndirectiveAllocas(Function* func, bool& changed); // 消除无用间接内存分配(phi节点)
|
||||||
void eliminateDeadRedundantLoadStore(Function* func, bool& changed); // 消除冗余加载和存储
|
void eliminateDeadRedundantLoadStore(Function* func, bool& changed); // 消除冗余加载和存储
|
||||||
bool isGlobal(Value *val);
|
|
||||||
bool isArr(Value *val);
|
|
||||||
void usedelete(Instruction *instr);
|
|
||||||
|
|
||||||
};
|
};
|
||||||
} // namespace sysy
|
} // namespace sysy
|
||||||
|
|||||||
@ -8,6 +8,7 @@
|
|||||||
#include "IR.h"
|
#include "IR.h"
|
||||||
#include "IRBuilder.h"
|
#include "IRBuilder.h"
|
||||||
#include "SysYIRAnalyser.h"
|
#include "SysYIRAnalyser.h"
|
||||||
|
#include "SysYIROptUtils.h"
|
||||||
|
|
||||||
namespace sysy {
|
namespace sysy {
|
||||||
/**
|
/**
|
||||||
@ -51,9 +52,6 @@ private:
|
|||||||
auto getPredIndex(BasicBlock *n, BasicBlock *s) -> int; ///< 获取前驱索引
|
auto getPredIndex(BasicBlock *n, BasicBlock *s) -> int; ///< 获取前驱索引
|
||||||
auto cascade(Instruction *instr, bool &changed, Function *func, BasicBlock *block,
|
auto cascade(Instruction *instr, bool &changed, Function *func, BasicBlock *block,
|
||||||
std::list<std::unique_ptr<Instruction>> &instrs) -> void; ///< 消除级联关系
|
std::list<std::unique_ptr<Instruction>> &instrs) -> void; ///< 消除级联关系
|
||||||
auto isGlobal(Value *val) -> bool; ///< 判断是否是全局变量
|
|
||||||
auto isArr(Value *val) -> bool; ///< 判断是否是数组
|
|
||||||
auto usedelete(Instruction *instr) -> void; ///< 删除指令相关的value-use-user关系
|
|
||||||
|
|
||||||
};
|
};
|
||||||
} // namespace sysy
|
} // namespace sysy
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "IR.h"
|
#include "IR.h"
|
||||||
#include "IRBuilder.h"
|
#include "IRBuilder.h"
|
||||||
|
#include "SysYIROptUtils.h"
|
||||||
|
|
||||||
namespace sysy {
|
namespace sysy {
|
||||||
/**
|
/**
|
||||||
@ -16,8 +17,6 @@ public:
|
|||||||
Reg2Mem(Module *pMoudle, IRBuilder *pBuilder) : pModule(pMoudle), pBuilder(pBuilder) {}
|
Reg2Mem(Module *pMoudle, IRBuilder *pBuilder) : pModule(pMoudle), pBuilder(pBuilder) {}
|
||||||
|
|
||||||
void DeletePhiInst();
|
void DeletePhiInst();
|
||||||
// 删除UD关系, 因为删除了phi指令会修改ud关系
|
|
||||||
void usedelete(Instruction *instr);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace sysy
|
} // namespace sysy
|
||||||
@ -10,6 +10,11 @@ namespace sysy {
|
|||||||
// 这些操作可以在SysY IR生成时就完成,但为了简化IR生成过程,
|
// 这些操作可以在SysY IR生成时就完成,但为了简化IR生成过程,
|
||||||
// 这里将其放在SysY IR生成后进行预处理
|
// 这里将其放在SysY IR生成后进行预处理
|
||||||
// 同时兼容phi节点的处理,可以再mem2reg后再次调用优化
|
// 同时兼容phi节点的处理,可以再mem2reg后再次调用优化
|
||||||
|
|
||||||
|
//TODO: 可增加的CFG优化
|
||||||
|
// - 简化条件分支(Branch Simplification),如条件恒真/恒假转为直接跳转
|
||||||
|
// - 合并连续的跳转指令(Jump Threading)在合并不可达块中似乎已经实现了
|
||||||
|
// - 基本块重排序(Block Reordering),提升局部性
|
||||||
class SysYOptPre {
|
class SysYOptPre {
|
||||||
private:
|
private:
|
||||||
Module *pModule;
|
Module *pModule;
|
||||||
@ -31,7 +36,6 @@ class SysYOptPre {
|
|||||||
void SysYBlockMerge(); // 合并基本块(主要针对嵌套if while的exit块,
|
void SysYBlockMerge(); // 合并基本块(主要针对嵌套if while的exit块,
|
||||||
// 也可以修改IR生成实现回填机制
|
// 也可以修改IR生成实现回填机制
|
||||||
void SysYAddReturn(); // 添加return指令(主要针对Void函数)
|
void SysYAddReturn(); // 添加return指令(主要针对Void函数)
|
||||||
void usedelete(Instruction *instr); // use删除
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace sysy
|
} // namespace sysy
|
||||||
|
|||||||
33
src/include/SysYIROptUtils.h
Normal file
33
src/include/SysYIROptUtils.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "IR.h"
|
||||||
|
|
||||||
|
namespace sysy {
|
||||||
|
|
||||||
|
// 优化工具类,包含一些通用的优化方法
|
||||||
|
// 这些方法可以在不同的优化 pass 中复用
|
||||||
|
// 例如:删除use关系,判断是否是全局变量等
|
||||||
|
class SysYIROptUtils{
|
||||||
|
|
||||||
|
public:
|
||||||
|
// 删除use关系
|
||||||
|
static void usedelete(Instruction *instr) {
|
||||||
|
for (auto &use : instr->getOperands()) {
|
||||||
|
Value* val = use->getValue();
|
||||||
|
val->removeUse(use);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 判断是否是全局变量
|
||||||
|
static bool isGlobal(Value *val) {
|
||||||
|
auto gval = dynamic_cast<GlobalValue *>(val);
|
||||||
|
return gval != nullptr;
|
||||||
|
}
|
||||||
|
// 判断是否是数组
|
||||||
|
static bool isArr(Value *val) {
|
||||||
|
auto aval = dynamic_cast<AllocaInst *>(val);
|
||||||
|
return aval != nullptr && aval->getNumDims() != 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}// namespace sysy
|
||||||
Reference in New Issue
Block a user