diff --git a/backend/RISCVISel.cpp b/backend/RISCVISel.cpp index 5d11eeb7..d5cb642c 100644 --- a/backend/RISCVISel.cpp +++ b/backend/RISCVISel.cpp @@ -467,6 +467,17 @@ void RISCVISel::InstLowering(BinaryInst* inst){ else assert(0&&"Illegal!"); break; } + case BinaryInst::Op_Xor: + { + if(inst->GetType()!=FloatType::NewFloatTypeGet()) { + if(ConstIRInt* constint = dynamic_cast(inst->GetOperand(1))) + ctx(Builder(RISCVMIR::_xori,inst)); + else + ctx(Builder(RISCVMIR::_xor,inst)); + } + else assert(0&&"Illegal!"); + break; + } default: assert(0&&"Invalid Opcode"); } diff --git a/include/ir/opt/ConstantFold.hpp b/include/ir/opt/ConstantFold.hpp index 57c3894f..04443ff8 100644 --- a/include/ir/opt/ConstantFold.hpp +++ b/include/ir/opt/ConstantFold.hpp @@ -8,7 +8,7 @@ class ConstantFolding public: Value* ConstantFoldInst(User* inst); static ConstantData* ConstantFoldLoadFromConstPtr(ConstantData* Ptr, Type* tp); -static ConstantData* ConstFoldBinary(BinaryInst::Operation Opcode, ConstantData* LHS, ConstantData* RHS); +static ConstantData* ConstFoldBinary(BinaryInst* inst, BinaryInst::Operation Opcode, ConstantData* LHS, ConstantData* RHS); static bool ReversedSubOperand(BinaryInst* inst); private: // Handle PhiInst @@ -27,11 +27,11 @@ Value* ConstFoldFloatCmp(BinaryInst::Operation Opcode, float LVal, float RVal); Value* ConstFoldCmp(BinaryInst::Operation Opcode, bool LVal, bool RVal); Value* ConstFoldMaxInst(Value* LHS, Value* RHS); Value* ConstFoldMinInst(Value* LHS, Value* RHS); +Value* ConstFoldSelectInst(Value* cond, Value* TrueVal, Value* FalseVal); // Handle SITFP Value* ConstantFoldSITFPInst(SITFP* inst); // Handle FPTSI Value* ConstantFoldFPTSIInst(FPTSI* inst); // Handle ZextInst Value* ConstantFoldZextInst(ZextInst* inst); - }; diff --git a/include/ir/opt/ConstantHoist.hpp b/include/ir/opt/ConstantHoist.hpp new file mode 100644 index 00000000..bb0aaf39 --- /dev/null +++ b/include/ir/opt/ConstantHoist.hpp @@ -0,0 +1,45 @@ +#pragma once +#include "../../../util/my_stl.hpp" +#include "../../lib/CFG.hpp" +#include "../Analysis/dominant.hpp" +#include "New_passManager.hpp" +#include "PassManagerBase.hpp" +#include + +class _AnalysisManager; + +class ConstantHoist : public _PassManagerBase +{ + struct HoistNode + { + User *LHS_Inst; + Value *LHS; + User *RHS_Inst; + Value *RHS; + int index; + HoistNode(User *LHS_Inst_, Value *LHS_, User *RHS_Inst_, Value *RHS_, int index_) + : LHS_Inst(LHS_Inst_), LHS(LHS_), RHS_Inst(RHS_Inst_), RHS(RHS_), index(index_) + { + } + }; + + private: + Function *func; + dominance *DomTree; + _AnalysisManager &AM; + std::vector HoistList; + std::unordered_map> InstIndex; + + bool RunOnBlock(BasicBlock *bb); + bool HoistInstInBlock(BasicBlock *TrueBlock, BasicBlock *FalseBlock); + + public: + ConstantHoist(Function *func_, _AnalysisManager &AM_) : func(func_), AM(AM_) + { + } + ~ConstantHoist() + { + HoistList.clear(); + } + bool Run(); +}; \ No newline at end of file diff --git a/include/ir/opt/InstructionSimplify.hpp b/include/ir/opt/InstructionSimplify.hpp index be0faeab..85749659 100644 --- a/include/ir/opt/InstructionSimplify.hpp +++ b/include/ir/opt/InstructionSimplify.hpp @@ -2,11 +2,11 @@ #include "../../lib/CFG.hpp" #include "ConstantProp.hpp" -Value* SimplifyBinOp(BinaryInst::Operation Opcode, Value* LHS, Value* RHS); +Value* SimplifyBinOp(BinaryInst* inst, BinaryInst::Operation Opcode, Value* LHS, Value* RHS); Value* SimplifyAddInst(Value* LHS, Value* RHS); Value* SimplifySubInst(Value* LHS, Value* RHS); Value* SimplifyMulInst(Value* LHS, Value* RHS); Value* SimplifyDivInst(Value* LHS, Value* RHS); Value* SimplifyModInst(Value* LHS, Value* RHS); -Value* SimplifyIcmpInst(BinaryInst::Operation Opcode, Value* LHS, Value* RHS); +Value* SimplifyIcmpInst(BinaryInst* inst, BinaryInst::Operation Opcode, Value* LHS, Value* RHS); bool MatchAddModInst(BasicBlock* cur); \ No newline at end of file diff --git a/include/ir/opt/New_passManager.hpp b/include/ir/opt/New_passManager.hpp index a5f59f54..2cad1200 100644 --- a/include/ir/opt/New_passManager.hpp +++ b/include/ir/opt/New_passManager.hpp @@ -34,6 +34,7 @@ #include "../../include/ir/opt/LoadElimination.hpp" #include "../../include/ir/opt/SelfStoreElimination.hpp" #include "../../include/ir/opt/ScalarStrengthReduce.hpp" +#include "../../include/ir/opt/ConstantHoist.hpp" #include #include #include @@ -72,7 +73,8 @@ enum PassName { loadeliminaion, selfstoreelimination, cachelookup, - scalarstrengthreduce + scalarstrengthreduce, + consthoist }; static struct option long_options[] = { @@ -106,6 +108,7 @@ static struct option long_options[] = { {"SelfStoreElimination", no_argument, 0, 31}, {"CacheLookUp", no_argument, 0, 32}, {"ScalarStrengthReduce", no_argument, 0, 33}, + {"consthoist", no_argument, 0, 34}, {"O0", no_argument, 0, 0}, {"O1", no_argument, 0, 1}, {"O2", no_argument, 0, 2}, diff --git a/include/lib/BaseCFG.hpp b/include/lib/BaseCFG.hpp index 605355df..d0dbe2d0 100644 --- a/include/lib/BaseCFG.hpp +++ b/include/lib/BaseCFG.hpp @@ -161,7 +161,8 @@ class User:public Value,public list_node SI2FP, BinaryUnknown, Max, - Min + Min, + Select }; OpID id; using UsePtr=std::unique_ptr; diff --git a/include/lib/CFG.hpp b/include/lib/CFG.hpp index 85442f70..9f4b81b6 100644 --- a/include/lib/CFG.hpp +++ b/include/lib/CFG.hpp @@ -246,6 +246,15 @@ class MinInst:public User void print()final; }; +class SelectInst : public User +{ + public: + SelectInst(Type *ty) : User{ty} {id = OpID::Select;} + SelectInst(Operand _Cond, Operand _TrueVal, Operand _FalseVal); + SelectInst* clone(std::unordered_map&)override; + void print() final; +}; + class PhiInst : public User { public: PhiInst(Type *ty) :oprandNum(0), User{ty} {id = OpID::Phi;} diff --git a/ir/opt/CSE.cpp b/ir/opt/CSE.cpp index 9bf91a81..2353067f 100644 --- a/ir/opt/CSE.cpp +++ b/ir/opt/CSE.cpp @@ -78,7 +78,7 @@ bool CSE::ProcessNode(CSENode *node) if (auto binary = dynamic_cast(inst)) { node->DelStoreValue(binary, CurGeneration); - if (Value *val = SimplifyBinOp(binary->getopration(), binary->GetOperand(0), binary->GetOperand(1))) + if (Value *val = SimplifyBinOp(binary, binary->getopration(), binary->GetOperand(0), binary->GetOperand(1))) { _DEBUG(std::cerr << "Can Handle BinaryInst: " << inst->GetName() << " as Value:" << val->GetName() << std::endl;) diff --git a/ir/opt/ConstantFold.cpp b/ir/opt/ConstantFold.cpp index 3f7d414e..119ea29c 100644 --- a/ir/opt/ConstantFold.cpp +++ b/ir/opt/ConstantFold.cpp @@ -17,6 +17,8 @@ Value *ConstantFolding::ConstantFoldInst(User *inst) return ConstFoldMaxInst(inst->GetOperand(0), inst->GetOperand(1)); else if(auto mininst = dynamic_cast(inst)) return ConstFoldMinInst(inst->GetOperand(0), inst->GetOperand(1)); + else if(auto select = dynamic_cast(inst)) + return ConstFoldSelectInst(select->GetOperand(0), select->GetOperand(1), select->GetOperand(2)); return nullptr; } @@ -44,7 +46,7 @@ Value *ConstantFolding::ConstantFoldBinaryInst(BinaryInst *inst) if (LHS->isConst() && RHS->isConst()) { - Value *Simplify = SimplifyBinOp(inst->getopration(), LHS, RHS); + Value *Simplify = SimplifyBinOp(inst, inst->getopration(), LHS, RHS); if (Simplify) { if (dynamic_cast(Simplify)) @@ -64,7 +66,7 @@ Value *ConstantFolding::ConstantFoldBinaryInst(BinaryInst *inst) if (type == InnerDataType::IR_Value_Float) return ConstantFoldBinaryFloat(inst, LHS, RHS); } - Value *Simplify = SimplifyBinOp(inst->getopration(), LHS, RHS); + Value *Simplify = SimplifyBinOp(inst, inst->getopration(), LHS, RHS); if (Simplify) return Simplify; if (inst->getopration() == BinaryInst::Op_Sub) @@ -351,9 +353,9 @@ Value *ConstantFolding::ConstFoldCmp(BinaryInst::Operation Opcode, bool LVal, bo return ConstIRBoolean::GetNewConstant(Result); } -ConstantData *ConstantFolding::ConstFoldBinary(BinaryInst::Operation Opcode, ConstantData *LHS, ConstantData *RHS) +ConstantData *ConstantFolding::ConstFoldBinary(BinaryInst* inst, BinaryInst::Operation Opcode, ConstantData *LHS, ConstantData *RHS) { - Value *Simplify = SimplifyBinOp(Opcode, LHS, RHS); + Value *Simplify = SimplifyBinOp(inst, Opcode, LHS, RHS); ConstantData *Simplify_ = static_cast(Simplify); if (Simplify_) { @@ -568,4 +570,15 @@ Value* ConstantFolding::ConstFoldMinInst(Value* LHS, Value* RHS) return ConstIRFloat::GetNewConstant(std::min(LVal, RVal)); } return nullptr; +} + +Value* ConstantFolding::ConstFoldSelectInst(Value* cond, Value* TrueVal, Value* FalseVal) +{ + auto Cond = dynamic_cast(cond); + if(!Cond) + return nullptr; + if(Cond->GetVal()) + return TrueVal; + else + return FalseVal; } \ No newline at end of file diff --git a/ir/opt/ConstantHoist.cpp b/ir/opt/ConstantHoist.cpp new file mode 100644 index 00000000..f23805e2 --- /dev/null +++ b/ir/opt/ConstantHoist.cpp @@ -0,0 +1,185 @@ +#include "../../include/ir/opt/ConstantHoist.hpp" + +bool ConstantHoist::Run() +{ + bool modified = false; + for (BasicBlock *block : *func) + modified |= RunOnBlock(block); + return modified; +} + +bool ConstantHoist::RunOnBlock(BasicBlock *block) +{ + bool modified = false; + User *Terminal = block->back(); + if (!dynamic_cast(Terminal)) + return false; + CondInst *Br = dynamic_cast(Terminal); + BasicBlock *TrueBlock = dynamic_cast(Br->GetOperand(1)); + BasicBlock *FalseBlock = dynamic_cast(Br->GetOperand(2)); + + if (TrueBlock == FalseBlock || TrueBlock == block || FalseBlock == block) + return false; + if (TrueBlock->GetUserlist().GetSize() != 1 || FalseBlock->GetUserlist().GetSize() != 1) + return false; + if (TrueBlock->Size() != FalseBlock->Size()) + return false; + if (!HoistInstInBlock(TrueBlock, FalseBlock)) + return false; + User *cmp = Br->GetOperand(0)->as(); + while (!HoistList.empty()) + { + modified = true; + HoistNode *node = HoistList.back(); + HoistList.pop_back(); + User *LHS_Inst = node->LHS_Inst; + Value *LHS = node->LHS; + User *RHS_Inst = node->RHS_Inst; + Value *RHS = node->RHS; + int index = node->index; + SelectInst *new_select = new SelectInst(cmp, LHS, RHS); + BasicBlock::mylist::iterator Pos(cmp); + Pos.insert_after(new_select); + LHS_Inst->RSUW(index, new_select); + RHS_Inst->RSUW(index, new_select); + modified = true; + } + BasicBlock::mylist::iterator Pos(Br); + for (auto inst = TrueBlock->begin(); inst != TrueBlock->end();) + { + User *handle = *inst; + ++inst; + handle->EraseFromParent(); + Pos.insert_before(handle); + } + delete Br; + return modified; +} + +bool ConstantHoist::HoistInstInBlock(BasicBlock *TrueBlock, BasicBlock *FalseBlock) +{ + bool modified = false; + int index = 0; + for (auto True_iter = TrueBlock->begin(), False_iter = FalseBlock->begin(); + True_iter != TrueBlock->end(), False_iter != FalseBlock->end(); ++True_iter, ++False_iter) + { + User *True_Inst = *True_iter; + User *False_Inst = *False_iter; + if (True_Inst->GetInstId() != False_Inst->GetInstId()) + return false; + if (True_Inst->GetType() != False_Inst->GetType()) + return false; + if (True_Inst->Getuselist().size() != False_Inst->Getuselist().size()) + return false; + InstIndex[TrueBlock][True_Inst] = index; + InstIndex[FalseBlock][False_Inst] = index; + index++; + } + for (auto True_iter = TrueBlock->begin(), False_iter = FalseBlock->begin(); + True_iter != TrueBlock->end(), False_iter != FalseBlock->end(); ++True_iter, ++False_iter) + { + User *True_Inst = *True_iter; + User *False_Inst = *False_iter; + if (dynamic_cast(True_Inst)) + continue; + for (int i = 0; i < True_Inst->Getuselist().size(); i++) + { + Value *True_Op = True_Inst->GetOperand(i); + Value *False_Op = False_Inst->GetOperand(i); + User *True_User = dynamic_cast(True_Op); + User *False_User = dynamic_cast(False_Op); + if (True_Op->GetType() != False_Op->GetType()) + return false; + if (dynamic_cast(True_Op) && dynamic_cast(False_Op)) + { + if (dynamic_cast(True_Op) != dynamic_cast(False_Op)) + { + modified = true; + HoistList.push_back(new HoistNode(True_Inst, True_Op, False_Inst, False_Op, i)); + } + } + else if (dynamic_cast(True_Op) && dynamic_cast(False_Op)) + { + if (dynamic_cast(True_Op) != dynamic_cast(False_Op)) + { + modified = true; + HoistList.push_back(new HoistNode(True_Inst, True_Op, False_Inst, False_Op, i)); + } + } + else if (dynamic_cast(True_Inst) && i == 0 && True_User && False_User && + True_User->GetParent() != TrueBlock && False_User->GetParent() != FalseBlock) + { + if (True_Op != False_Op) + { + modified = true; + HoistList.push_back(new HoistNode(True_Inst, True_Op, False_Inst, False_Op, i)); + } + } + else if (True_User && False_User && True_User->GetParent() == TrueBlock && + False_User->GetParent() == FalseBlock) + { + if (InstIndex[TrueBlock][True_User] != InstIndex[FalseBlock][False_User]) + return false; + } + else if (True_User && False_User && + (True_User->GetParent() == TrueBlock || False_User->GetParent() == FalseBlock)) + return false; + } + } + User *True_Br = TrueBlock->back(); + if (dynamic_cast(True_Br)) + { + BasicBlock *Block_t = True_Br->GetOperand(1)->as(); + BasicBlock *Block_f = True_Br->GetOperand(2)->as(); + for (User *inst : *Block_t) + { + if (auto phi = dynamic_cast(inst)) + { + Value *True_Value = phi->ReturnValIn(TrueBlock); + Value *False_Value = phi->ReturnValIn(FalseBlock); + if (True_Value != False_Value) + { + HoistList.clear(); + return false; + } + } + else + break; + } + for (User *inst : *Block_f) + { + if (auto phi = dynamic_cast(inst)) + { + Value *True_Value = phi->ReturnValIn(TrueBlock); + Value *False_Value = phi->ReturnValIn(FalseBlock); + if (True_Value != False_Value) + { + HoistList.clear(); + return false; + } + } + else + break; + } + } + else if (dynamic_cast(True_Br)) + { + BasicBlock *Block_t = True_Br->GetOperand(0)->as(); + for (User *inst : *Block_t) + { + if (auto phi = dynamic_cast(inst)) + { + Value *True_Value = phi->ReturnValIn(TrueBlock); + Value *False_Value = phi->ReturnValIn(FalseBlock); + if (True_Value != False_Value) + { + HoistList.clear(); + return false; + } + } + else + break; + } + } + return modified; +} \ No newline at end of file diff --git a/ir/opt/InstructionSimplify.cpp b/ir/opt/InstructionSimplify.cpp index 0e40f696..3b3a93d0 100644 --- a/ir/opt/InstructionSimplify.cpp +++ b/ir/opt/InstructionSimplify.cpp @@ -1,7 +1,7 @@ #include "../../include/ir/opt/InstructionSimplify.hpp" #include -Value *SimplifyBinOp(BinaryInst::Operation Opcode, Value *LHS, Value *RHS) { +Value *SimplifyBinOp(BinaryInst* inst, BinaryInst::Operation Opcode, Value *LHS, Value *RHS) { switch (Opcode) { case BinaryInst::Op_Add: return SimplifyAddInst(LHS, RHS); @@ -21,7 +21,7 @@ Value *SimplifyBinOp(BinaryInst::Operation Opcode, Value *LHS, Value *RHS) { case BinaryInst::Op_GE: case BinaryInst::Op_L: case BinaryInst::Op_LE: - return SimplifyIcmpInst(Opcode, LHS, RHS); + return SimplifyIcmpInst(inst, Opcode, LHS, RHS); default: return nullptr; } @@ -177,7 +177,7 @@ Value *SimplifyModInst(Value *LHS, Value *RHS) { return nullptr; } -Value *SimplifyIcmpInst(BinaryInst::Operation Opcode, Value *LHS, Value *RHS) { +Value *SimplifyIcmpInst(BinaryInst* inst, BinaryInst::Operation Opcode, Value *LHS, Value *RHS) { // false and X -> false if (Opcode == BinaryInst::Op_And) { auto LHSBool = dynamic_cast(LHS); @@ -246,6 +246,39 @@ Value *SimplifyIcmpInst(BinaryInst::Operation Opcode, Value *LHS, Value *RHS) { } } + // ( X == a ) && ( Y == b ) -> ( X ^ a ) || ( Y ^ b ) == 0 实测慢了 + // if(Opcode == BinaryInst::Op_And) + // { + // if(dynamic_cast(LHS) && dynamic_cast(RHS)) + // { + // BinaryInst* lhs = dynamic_cast(LHS); + // BinaryInst* rhs = dynamic_cast(RHS); + // if(lhs->getopration() == BinaryInst::Operation::Op_E && rhs->getopration() == BinaryInst::Operation::Op_E) + // { + // BinaryInst* LHS_Xor = new BinaryInst(lhs->GetOperand(0), BinaryInst::Operation::Op_Xor, lhs->GetOperand(1)); + // BinaryInst* RHS_Xor = new BinaryInst(rhs->GetOperand(0), BinaryInst::Operation::Op_Xor, rhs->GetOperand(1)); + // lhs->RAUW(LHS_Xor); + // rhs->RAUW(RHS_Xor); + // delete lhs; + // delete rhs; + // BinaryInst* New_Or = new BinaryInst(LHS_Xor, BinaryInst::Operation::Op_Or, RHS_Xor); + // BinaryInst* New_Cmp = nullptr; + // if(New_Or->GetType()->GetTypeEnum() == InnerDataType::IR_Value_INT) + // New_Cmp = new BinaryInst(New_Or, BinaryInst::Operation::Op_E, ConstIRInt::GetNewConstant(0)); + // else if(New_Or->GetType()->GetTypeEnum() == InnerDataType::IR_Value_Float) + // New_Cmp = new BinaryInst(New_Or, BinaryInst::Operation::Op_E, ConstIRFloat::GetNewConstant(0.0)); + // else + // New_Cmp = new BinaryInst(New_Or, BinaryInst::Operation::Op_E, ConstIRBoolean::GetNewConstant(false)); + // BasicBlock::mylist::iterator Pos(inst); + // Pos.insert_before(LHS_Xor); + // Pos.insert_before(RHS_Xor); + // Pos.insert_before(New_Or); + // Pos.insert_before(New_Cmp); + // return New_Cmp; + // } + // } + // } + // X == X -> true if (LHS == RHS && Opcode == BinaryInst::Op_E) return ConstIRBoolean::GetNewConstant(true); diff --git a/ir/opt/LoopRotate.cpp b/ir/opt/LoopRotate.cpp index 1bc7498e..652f10e0 100644 --- a/ir/opt/LoopRotate.cpp +++ b/ir/opt/LoopRotate.cpp @@ -93,6 +93,7 @@ bool LoopRotate::RotateLoop(LoopInfo *loop, bool Succ) { new_inst->GetOperand(0)->isConst() && new_inst->GetOperand(1)->isConst()) { simplify = ConstantFolding::ConstFoldBinary( + dynamic_cast(new_inst), dynamic_cast(new_inst)->getopration(), dynamic_cast(new_inst->GetOperand(0)), dynamic_cast(new_inst->GetOperand(1))); diff --git a/ir/opt/ScalarStrengthReduce.cpp b/ir/opt/ScalarStrengthReduce.cpp index 19c55621..8eb5aed7 100644 --- a/ir/opt/ScalarStrengthReduce.cpp +++ b/ir/opt/ScalarStrengthReduce.cpp @@ -112,6 +112,7 @@ bool ScalarStrengthReduce::RunOnLoop(LoopInfo *loop) iter.insert_before(new_trunc); phi->RAUW(new_trunc); delete phi; + delete phi_; return true; } } @@ -148,6 +149,7 @@ bool ScalarStrengthReduce::RunOnLoop(LoopInfo *loop) } } } + return false; } Value *ScalarStrengthReduce::CaculateTimes(LoopInfo *loop) diff --git a/ir/opt/new_passManager.cpp b/ir/opt/new_passManager.cpp index a1be5ff7..ca941e36 100644 --- a/ir/opt/new_passManager.cpp +++ b/ir/opt/new_passManager.cpp @@ -89,6 +89,9 @@ void _PassManager::DecodeArgs(int argc, char *argv[]) { case scalarstrengthreduce: AddPass(scalarstrengthreduce); break; + case consthoist: + AddPass(consthoist); + break; case O0: level = O0; break; @@ -333,7 +336,9 @@ bool _PassManager::CommonPass(_AnalysisManager &AM) { RunLevelPass(DCE, curfunc, mody) // constprop RunLevelPass(ConstantProp, curfunc, mody); - + RunLevelPass(ConstantHoist, curfunc,modified); + RunLevelPass(cfgSimplify, curfunc, modified) + PassChangedBegin(curfunc) PassChangedEnd // reassociate RunLevelPass(Reassociate, curfunc, mody); @@ -347,7 +352,6 @@ bool _PassManager::CommonPass(_AnalysisManager &AM) { PassChangedBegin(curfunc) PassChangedEnd RunLevelPass(cfgSimplify, curfunc, mody); - // TRE // RunLevelPass(TailRecurseEliminator, curfunc, mody) return mody; } @@ -537,6 +541,11 @@ void _PassManager::RunOnTest() { auto m_blockmerge = RunImpl(curfunc, AM); break; } + case consthoist: + { + auto m_consthoist = RunImpl(curfunc, AM); + break; + } default: { assert(0); } diff --git a/ir/opt/reassociate.cpp b/ir/opt/reassociate.cpp index 318995f7..192d676c 100644 --- a/ir/opt/reassociate.cpp +++ b/ir/opt/reassociate.cpp @@ -257,7 +257,7 @@ Value *Reassociate::OptExp(BinaryInst *exp, if (C == nullptr) C = temp; else - C = ConstantFolding::ConstFoldBinary(exp->getopration(), C, temp); + C = ConstantFolding::ConstFoldBinary(exp, exp->getopration(), C, temp); } //按理说做完常量折叠后,不会出现这种情况了 if (LinerizedOp.empty()) { diff --git a/lib/CFG.cpp b/lib/CFG.cpp index 24801fba..b4de0f23 100644 --- a/lib/CFG.cpp +++ b/lib/CFG.cpp @@ -780,6 +780,37 @@ MinInst* MinInst::clone(std::unordered_map& mapping) return normal_clone(this, mapping); } +SelectInst::SelectInst(Operand _cond, Operand _A, Operand _B) + : User(_A->GetType()) { + add_use(_cond); + add_use(_A); + add_use(_B); + id = OpID::Select; +} + +SelectInst* SelectInst::clone(std::unordered_map& mapping) +{ + return normal_clone(this, mapping); +} + +void SelectInst::print() +{ + Value::print(); + std::cout << " = select "; + uselist[0]->GetValue()->GetType()->print(); + std::cout << " "; + uselist[0]->GetValue()->print(); + std::cout << ", "; + uselist[1]->GetValue()->GetType()->print(); + std::cout << " "; + uselist[1]->GetValue()->print(); + std::cout << ", "; + uselist[2]->GetValue()->GetType()->print(); + std::cout << " "; + uselist[2]->GetValue()->print(); + std::cout << '\n'; +} + BasicBlock::BasicBlock() : Value(VoidType::NewVoidTypeGet()){}; Operand BasicBlock::GenerateLoadInst(Operand data) { auto tmp = new LoadInst(data);