diff --git a/.gitignore b/.gitignore index c10e61c..32dccde 100644 --- a/.gitignore +++ b/.gitignore @@ -36,7 +36,7 @@ doxygen !/testdata/functional/*.out !/testdata/h_functional/*.out -!/testdata/performance/*.out +testdata/performance/ build/ .antlr .vscode/ diff --git a/src/include/midend/IR.h b/src/include/midend/IR.h index 92539dc..9148edc 100644 --- a/src/include/midend/IR.h +++ b/src/include/midend/IR.h @@ -1007,6 +1007,7 @@ class PhiInst : public Instruction { void replaceIncomingBlock(BasicBlock *oldBlock, BasicBlock *newBlock, Value *newValue); void refreshMap() { blk2val.clear(); + vsize = getNumOperands() / 2; for (unsigned i = 0; i < vsize; ++i) { blk2val[getIncomingBlock(i)] = getIncomingValue(i); } diff --git a/src/include/midend/Pass/Optimize/SysYIROptUtils.h b/src/include/midend/Pass/Optimize/SysYIROptUtils.h index 48d2f26..81062e1 100644 --- a/src/include/midend/Pass/Optimize/SysYIROptUtils.h +++ b/src/include/midend/Pass/Optimize/SysYIROptUtils.h @@ -109,6 +109,34 @@ public: } + // PHI指令消除相关方法 + static bool eliminateRedundantPhisInFunction(Function* func){ + bool changed = false; + std::vector toDelete; + for (auto &bb : func->getBasicBlocks()) { + for (auto &inst : bb->getInstructions()) { + if (auto phi = dynamic_cast(inst.get())) { + auto incoming = phi->getIncomingValues(); + if(DEBUG){ + std::cout << "Checking Phi: " << phi->getName() << " with " << incoming.size() << " incoming values." << std::endl; + } + if (incoming.size() == 1) { + Value *singleVal = incoming[0].second; + inst->replaceAllUsesWith(singleVal); + toDelete.push_back(inst.get()); + } + } + else + break; // 只处理Phi指令 + } + } + for (auto *phi : toDelete) { + usedelete(phi); + changed = true; // 标记为已更改 + } + return changed; // 返回是否有删除发生 + } + //该实现参考了libdivide的算法 static std::pair computeMulhMagicNumbers(int divisor) { diff --git a/src/midend/IR.cpp b/src/midend/IR.cpp index d35e16b..5ed1777 100644 --- a/src/midend/IR.cpp +++ b/src/midend/IR.cpp @@ -757,7 +757,7 @@ void BinaryInst::print(std::ostream &os) const { auto lhs_hash = std::hash{}(static_cast(getLhs())); auto rhs_hash = std::hash{}(static_cast(getRhs())); size_t combined_hash = inst_hash ^ (lhs_hash << 1) ^ (rhs_hash << 2); - std::string tmpName = "tmp_icmp_" + std::to_string(combined_hash % 1000000); + std::string tmpName = "tmp_icmp_" + std::to_string(combined_hash % 1000000007); os << "%" << tmpName << " = " << getKindString() << " " << *getLhs()->getType() << " "; printOperand(os, getLhs()); os << ", "; @@ -772,7 +772,7 @@ void BinaryInst::print(std::ostream &os) const { auto lhs_hash = std::hash{}(static_cast(getLhs())); auto rhs_hash = std::hash{}(static_cast(getRhs())); size_t combined_hash = inst_hash ^ (lhs_hash << 1) ^ (rhs_hash << 2); - std::string tmpName = "tmp_fcmp_" + std::to_string(combined_hash % 1000000); + std::string tmpName = "tmp_fcmp_" + std::to_string(combined_hash % 1000000007); os << "%" << tmpName << " = " << getKindString() << " " << *getLhs()->getType() << " "; printOperand(os, getLhs()); os << ", "; @@ -834,7 +834,7 @@ void CondBrInst::print(std::ostream &os) const { if (condName.empty()) { // 使用条件值地址的哈希值作为唯一标识 auto ptr_hash = std::hash{}(static_cast(condition)); - condName = "const_" + std::to_string(ptr_hash % 100000); + condName = "const_" + std::to_string(ptr_hash % 1000000007); } // 组合指令地址、条件地址和目标块地址的哈希来确保唯一性 @@ -843,7 +843,7 @@ void CondBrInst::print(std::ostream &os) const { auto then_hash = std::hash{}(static_cast(getThenBlock())); auto else_hash = std::hash{}(static_cast(getElseBlock())); size_t combined_hash = inst_hash ^ (cond_hash << 1) ^ (then_hash << 2) ^ (else_hash << 3); - std::string uniqueSuffix = std::to_string(combined_hash % 1000000); + std::string uniqueSuffix = std::to_string(combined_hash % 1000000007); os << "%tmp_cond_" << condName << "_" << uniqueSuffix << " = icmp ne i32 "; printOperand(os, condition); diff --git a/src/midend/Pass/Optimize/DCE.cpp b/src/midend/Pass/Optimize/DCE.cpp index 06a4822..f89781e 100644 --- a/src/midend/Pass/Optimize/DCE.cpp +++ b/src/midend/Pass/Optimize/DCE.cpp @@ -74,6 +74,7 @@ void DCEContext::run(Function *func, AnalysisManager *AM, bool &changed) { } } } + changed |= SysYIROptUtils::eliminateRedundantPhisInFunction(func); // 如果有活跃指令,则标记为已更改 } // 判断指令是否是"天然活跃"的实现 diff --git a/src/midend/Pass/Optimize/GVN.cpp b/src/midend/Pass/Optimize/GVN.cpp index 09b67a1..047ae52 100644 --- a/src/midend/Pass/Optimize/GVN.cpp +++ b/src/midend/Pass/Optimize/GVN.cpp @@ -39,7 +39,7 @@ bool GVN::runOnFunction(Function *func, AnalysisManager &AM) { } std::cout << "=== GVN completed for function: " << func->getName() << " ===" << std::endl; } - + changed |= SysYIROptUtils::eliminateRedundantPhisInFunction(func); return changed; } diff --git a/src/midend/Pass/Optimize/GlobalStrengthReduction.cpp b/src/midend/Pass/Optimize/GlobalStrengthReduction.cpp index e8254a2..404cf7b 100644 --- a/src/midend/Pass/Optimize/GlobalStrengthReduction.cpp +++ b/src/midend/Pass/Optimize/GlobalStrengthReduction.cpp @@ -671,13 +671,13 @@ bool GlobalStrengthReductionContext::reduceDivision(BinaryInst *inst) { } // x / c = x * magic_number (魔数乘法优化 - 使用libdivide算法) - if (isConstantInt(rhs, constVal) && constVal > 1 && constVal != (uint32_t)(-1)) { - // auto magicPair = computeMulhMagicNumbers(static_cast(constVal)); - Value* magicResult = createMagicDivisionLibdivide(inst, static_cast(constVal)); - replaceWithOptimized(inst, magicResult); - divisionOptCount++; - return true; - } + // if (isConstantInt(rhs, constVal) && constVal > 1 && constVal != (uint32_t)(-1)) { + // // auto magicPair = computeMulhMagicNumbers(static_cast(constVal)); + // Value* magicResult = createMagicDivisionLibdivide(inst, static_cast(constVal)); + // replaceWithOptimized(inst, magicResult); + // divisionOptCount++; + // return true; + // } return false; } diff --git a/src/midend/Pass/Optimize/InductionVariableElimination.cpp b/src/midend/Pass/Optimize/InductionVariableElimination.cpp index 8055efa..56bb22a 100644 --- a/src/midend/Pass/Optimize/InductionVariableElimination.cpp +++ b/src/midend/Pass/Optimize/InductionVariableElimination.cpp @@ -133,6 +133,7 @@ bool InductionVariableEliminationContext::run(Function* F, AnalysisManager& AM) printDebugInfo(); } + modified |= SysYIROptUtils::eliminateRedundantPhisInFunction(F); return modified; } diff --git a/src/midend/Pass/Optimize/LoopStrengthReduction.cpp b/src/midend/Pass/Optimize/LoopStrengthReduction.cpp index 0edbed4..33751df 100644 --- a/src/midend/Pass/Optimize/LoopStrengthReduction.cpp +++ b/src/midend/Pass/Optimize/LoopStrengthReduction.cpp @@ -661,9 +661,9 @@ bool StrengthReductionContext::replaceOriginalInstruction(StrengthReductionCandi case StrengthReductionCandidate::DIVIDE_CONST: { // 任意常数除法 - builder->setPosition(candidate->containingBlock, - candidate->containingBlock->findInstIterator(candidate->originalInst)); - replacementValue = generateConstantDivisionReplacement(candidate, builder); + // builder->setPosition(candidate->containingBlock, + // candidate->containingBlock->findInstIterator(candidate->originalInst)); + // replacementValue = generateConstantDivisionReplacement(candidate, builder); break; } @@ -683,17 +683,19 @@ bool StrengthReductionContext::replaceOriginalInstruction(StrengthReductionCandi ); // 检查原值是否为负数 - Value* zero = ConstantInteger::get(0); - Value* isNegative = builder->createICmpLTInst(candidate->inductionVar, zero); + Value* shift31condidata = builder->createBinaryInst( + Instruction::Kind::kSra, candidate->inductionVar->getType(), + candidate->inductionVar, ConstantInteger::get(31) + ); // 如果为负数,需要调整结果 - Value* adjustment = ConstantInteger::get(candidate->multiplier); - Value* adjustedTemp = builder->createAddInst(temp, adjustment); - - // 使用条件分支来模拟select操作 - // 为简化起见,这里先用一个更复杂但可工作的方式 - // 实际应该创建条件分支,但这里先简化处理 - replacementValue = temp; // 简化版本,假设大多数情况下不是负数 + Value* adjustment = builder->createAndInst(shift31condidata, maskConstant); + Value* adjustedTemp = builder->createAddInst(candidate->inductionVar, adjustment); + Value* adjustedResult = builder->createBinaryInst( + Instruction::Kind::kAnd, candidate->inductionVar->getType(), + adjustedTemp, maskConstant + ); + replacementValue = adjustedResult; } else { // 非负数的取模,直接使用位与 replacementValue = builder->createBinaryInst( diff --git a/src/midend/Pass/Optimize/SCCP.cpp b/src/midend/Pass/Optimize/SCCP.cpp index 8fbda0b..d0fa138 100644 --- a/src/midend/Pass/Optimize/SCCP.cpp +++ b/src/midend/Pass/Optimize/SCCP.cpp @@ -1357,9 +1357,8 @@ void SCCPContext::run(Function *func, AnalysisManager &AM) { bool changed_control_flow = SimplifyControlFlow(func); // 如果任何一个阶段修改了 IR,标记分析结果为失效 - if (changed_constant_propagation || changed_control_flow) { - // AM.invalidate(); // 假设有这样的方法来使所有分析结果失效 - } + bool changed = changed_constant_propagation || changed_control_flow; + changed |= SysYIROptUtils::eliminateRedundantPhisInFunction(func); } // SCCP Pass methods