@@ -102,13 +102,16 @@ void create_basic_blocks_for_mfunc(MachineFunction &src, MachineFunction &dst,
102102 std::unordered_map<MachineBasicBlock *, MachineBasicBlock *> block_map;
103103 // One cannot simply loop over mfunc as we insert new blocks into it
104104 for (auto &mbb : src) {
105+ assert (all_of (mbb.successors (),
106+ [&](auto *succ) { return succ->getParent () == &src; }));
105107 auto [new_mblock, new_block] = clone_basic_block (mbb, dst);
106108 m2b.insert ({new_mblock, new_block});
107- block_map.insert ({ &mbb, new_mblock} );
109+ block_map.try_emplace ( &mbb, new_mblock);
108110 }
109111 for (auto &mbb : dst) {
110- for (auto *succ : mbb.successors ())
112+ for (auto *succ : mbb.successors ()) {
111113 replace_uses_of_block_with (mbb, *succ, *block_map.at (succ));
114+ }
112115 }
113116 for (auto &block : dst.getFunction ()) {
114117 for (auto &inst : block)
@@ -124,18 +127,6 @@ void create_basic_blocks_for_mfunc(MachineFunction &src, MachineFunction &dst,
124127 return succ->getParent () == mbb.getParent ();
125128 });
126129 }));
127-
128- for (auto &mbb : dst) {
129- for (auto &minst : mbb) {
130- if (minst.isBranch ()) {
131- auto dst_mbb = llvm::find_if (minst.operands (),
132- [](auto &op) { return op.isMBB (); });
133- assert (dst_mbb != minst.operands_end ());
134- assert (!block_map.count (dst_mbb->getMBB ()));
135- assert (dst_mbb->getMBB ()->getParent () == &dst);
136- }
137- }
138- }
139130}
140131
141132void fill_module_with_instrs (Module &m, const instr_impl &instrs) {
@@ -284,8 +275,9 @@ void load_registers(BasicBlock &block, BasicBlock::iterator pos, reg2vals &rmap,
284275 for (auto &&[idx, rclass] : reg_stats | views::enumerate) {
285276 auto *array_type = state.getElementType (idx);
286277 auto *arr_idx = ConstantInt::get (ctx, APInt (32 , idx));
287- auto *array_ptr = builder.CreateGEP (
288- &state, state_arg, ArrayRef<Value *>{arr_idx}, rclass.get_name ());
278+ auto *array_ptr = builder.CreateGEP (&state, state_arg,
279+ ArrayRef<Value *>{const_zero, arr_idx},
280+ rclass.get_name ());
289281 for (auto &&[reg_idx, val] : rmap | views::filter ([&rclass](auto r) {
290282 return rclass.contains (r.first );
291283 }) | views::enumerate) {
@@ -642,8 +634,13 @@ auto generate_branch(const MachineInstr &minst, BasicBlock &bb,
642634 auto name = get_instruction_name (minst, *iinfo);
643635 auto *m = bb.getParent ()->getParent ();
644636 auto *func = m->getFunction (name);
645- if (!func)
646- throw std::runtime_error (" Could not find \" " + name + " \" in module" );
637+ if (!func) {
638+ std::string instr;
639+ raw_string_ostream ss (instr);
640+ minst.print (ss);
641+ throw std::runtime_error (" Could not find \" " + name +
642+ " \" in module: " + instr);
643+ }
647644 auto op_to_val = [&](auto &mop) {
648645 return operand_to_value (mop, bb, target_machine, rmap, reg_stats, insts);
649646 };
@@ -788,8 +785,8 @@ static auto generate_load_store_from_stack(
788785 auto *offset = [&] -> Value * {
789786 if (offset_it == uses.end ())
790787 return ConstantInt::get (ctx, APInt (64 , 0 ));
791- return ConstantInt::get (ctx,
792- APInt (64 , -offset_it-> getImm () / reg_bytesize ));
788+ auto off = -offset_it-> getImm () / reg_bytesize;
789+ return ConstantInt::get (ctx, APInt (64 , off ));
793790 }();
794791 auto *sp =
795792 get_stack_pointer_value (instrs, rmap, builder, target_machine, reg_stats);
@@ -806,15 +803,21 @@ static auto generate_load_store_from_stack(
806803 auto *iinfo = target_machine.getMCInstrInfo ();
807804 auto name = get_instruction_name (minst, *iinfo);
808805 auto *m = bb.getParent ()->getParent ();
809- auto *func = m->getFunction (name);
810- if (!func)
811- throw std::runtime_error (" Could not find \" " + name + " \" in module" );
806+
812807 auto *inserted = [&] -> Value * {
813808 // Loading value from stack
814809 if (minst.mayLoad ()) {
815810 if (minst.mayStore ())
816811 throw std::runtime_error (" Unsupported stack manipulation. Instruction "
817812 " can both load and store" );
813+ auto *func = m->getFunction (name);
814+ if (!func) {
815+ std::string instr;
816+ raw_string_ostream ss (instr);
817+ minst.print (ss);
818+ throw std::runtime_error (" Could not find \" " + name +
819+ " \" in module: " + instr);
820+ }
818821 auto *ret_type = func->getFunctionType ()->getReturnType ();
819822 return builder.CreateLoad (ret_type, addr);
820823 }
@@ -829,8 +832,9 @@ static auto generate_load_store_from_stack(
829832 return builder.CreateStore (value, addr);
830833 }();
831834 // save result to register
832- if (!minst.defs ().empty ())
835+ if (!minst.defs ().empty ()) {
833836 builder.CreateStore (inserted, rmap.at (minst.defs ().begin ()->getReg ()));
837+ }
834838 return inserted;
835839}
836840
@@ -929,18 +933,16 @@ static bool is_return(const MachineInstr &minst, const instr_impl &instrs,
929933static bool is_call (const MachineInstr &minst, const TargetMachine &tmachine) {
930934 if (minst.isCall ())
931935 return true ;
932- if (minst.isPseudo ())
933- return false ;
934936 // TODO: create mia only once
935937 MCInst inst;
936938 inst.setOpcode (minst.getOpcode ());
937939 std::unique_ptr<MCInstrAnalysis> mia (
938940 tmachine.getTarget ().createMCInstrAnalysis (tmachine.getMCInstrInfo ()));
939941 assert (mia);
940- return mia->isCall (inst) && std::find_if ( minst.operands_begin (),
941- minst.operands_end (), []( auto &o) {
942- return o.isGlobal ();
943- }) != minst.operands_end ();
942+ return ( mia->isCall (inst) || minst.isUnconditionalBranch ()) &&
943+ std::find_if ( minst.operands_begin (), minst. operands_end (),
944+ []( auto &o) { return o.isGlobal (); }) !=
945+ minst.operands_end ();
944946}
945947static bool is_indirect_branch (const MachineInstr &minst,
946948 const instr_impl &instrs,
@@ -955,7 +957,9 @@ static bool is_indirect_branch(const MachineInstr &minst,
955957
956958static bool is_branch (const MachineInstr &minst,
957959 const TargetMachine &tmachine) {
958- if (minst.isBranch ())
960+ if (minst.isBranch () &&
961+ std::find_if (minst.operands_begin (), minst.operands_end (),
962+ [](auto &o) { return o.isMBB (); }) != minst.operands_end ())
959963 return true ;
960964 // TODO: create mia only once
961965 MCInst inst;
@@ -1017,18 +1021,21 @@ auto generate_instruction(const MachineInstr &minst, BasicBlock &bb,
10171021 if (is_call (minst, target_machine))
10181022 return generate_call (minst, builder, bb, rmap, target_machine, state,
10191023 reg_stats, functions_nop);
1020- if (minst.mayLoadOrStore ()) {
1021- // Instructions that are not considered stack manipulation are generated
1022- // just like any other instruction
1023- if (is_stack_manipulation (minst, sptrack))
1024- return generate_load_store_from_stack (minst, builder, bb, rmap, instrs,
1025- target_machine, state, reg_stats);
1024+ if (is_stack_manipulation (minst, sptrack)) {
1025+ return generate_load_store_from_stack (minst, builder, bb, rmap, instrs,
1026+ target_machine, state, reg_stats);
10261027 }
1028+
10271029 // TODO: track stack pointerS
10281030 auto *m = bb.getParent ()->getParent ();
10291031 auto *func = m->getFunction (name);
1030- if (!func)
1031- throw std::runtime_error (" Could not find \" " + name + " \" in module" );
1032+ if (!func) {
1033+ std::string instr;
1034+ raw_string_ostream ss (instr);
1035+ minst.print (ss);
1036+ throw std::runtime_error (" Could not find \" " + name +
1037+ " \" in module: " + instr);
1038+ }
10321039 auto uses = minst.uses ();
10331040 bool uses_sp = ranges::find_if (uses, [&](auto &u) {
10341041 return u.isReg () && sptrack.is_stack_pointer (u.getReg ());
@@ -1037,8 +1044,7 @@ auto generate_instruction(const MachineInstr &minst, BasicBlock &bb,
10371044 !minst.defs ().empty () && minst.defs ().begin ()->isReg () && uses_sp;
10381045 if (is_stack_pointer_manipulation) {
10391046 auto dst = minst.defs ().begin ()->getReg ();
1040- if (sptrack.is_stack_pointer (dst))
1041- sptrack.add (dst);
1047+ sptrack.add (dst);
10421048 return generate_stack_pointer_modification (
10431049 minst, builder, bb, target_machine, rmap, instrs, reg_stats);
10441050 }
@@ -1091,8 +1097,12 @@ void fill_ir_for_bb(MachineBasicBlock &mbb, reg2vals &rmap,
10911097 auto last = std::prev (mbb.end ());
10921098 if (!is_branch (*last, target_machine) &&
10931099 !is_return (*last, instrs, target_machine)) {
1094- auto succ = std::next (mbb.getIterator ());
1095- builder.CreateBr (m2b[std::addressof (*succ)]);
1100+ if (is_call (*last, target_machine)) {
1101+ builder.CreateRetVoid ();
1102+ } else {
1103+ auto succ = std::next (mbb.getIterator ());
1104+ builder.CreateBr (m2b[std::addressof (*succ)]);
1105+ }
10961106 }
10971107}
10981108
0 commit comments