28#include <llvm/ADT/PostOrderIterator.h>
29#include <llvm/ADT/StringExtras.h>
30#include <llvm/IR/BasicBlock.h>
31#include <llvm/IR/Constants.h>
32#include <llvm/IR/Function.h>
33#include <llvm/IR/Instructions.h>
34#include <llvm/IR/IntrinsicInst.h>
35#include <llvm/IR/Intrinsics.h>
36#include <llvm/IR/Module.h>
90 has(const ::llvm::BasicBlock * bb)
const noexcept
102 get(const ::llvm::BasicBlock * bb)
const noexcept
107 inline const ::llvm::BasicBlock *
116 bbmap_ = std::move(bbmap);
129 return vmap_.find(value)->second;
136 vmap_[value] = variable;
170 std::unordered_map<const ::llvm::Value *, const llvm::Variable *>
vmap_;
177 std::vector<std::unique_ptr<llvm::ThreeAddressCode>> &,
182 ::llvm::Instruction * instruction,
183 std::vector<std::unique_ptr<ThreeAddressCode>> & threeAddressCodes,
194 auto node = ctx.
node();
201 node->add_dependency(data->node());
207 if (
auto c = ::llvm::dyn_cast<::llvm::Constant>(v))
218 if (
auto fntype = std::dynamic_pointer_cast<const rvsdg::FunctionType>(var->
Type()))
220 auto operation = std::make_unique<FunctionToPointerOperation>(fntype);
221 std::unique_ptr<ThreeAddressCode> ptr_cast =
223 var = ptr_cast->result(0);
224 tacs.push_back(std::move(ptr_cast));
233 if (value.isNegative())
236 auto str = toString(value, 2,
false);
237 std::reverse(str.begin(), str.end());
240 if (value.isNegative())
241 vr = vr.
sext(value.getBitWidth() - str.size());
243 vr = vr.
zext(value.getBitWidth() - str.size());
251 typedef ::llvm::Attribute::AttrKind ak;
253 static std::unordered_map<::llvm::Attribute::AttrKind, Attribute::kind> map(
368 return { kind, attribute.getValueAsInt() };
376 if (attribute.getKindAsEnum() == ::llvm::Attribute::AttrKind::ByVal)
378 auto type = typeConverter.
ConvertLlvmType(*attribute.getValueAsType());
382 if (attribute.getKindAsEnum() == ::llvm::Attribute::AttrKind::StructRet)
384 auto type = typeConverter.
ConvertLlvmType(*attribute.getValueAsType());
391static StringAttribute
395 return { attribute.getKindAsString().str(), attribute.getValueAsString().str() };
402 for (
auto & attribute : as)
404 if (attribute.isEnumAttribute())
408 else if (attribute.isIntAttribute())
412 else if (attribute.isTypeAttribute())
416 else if (attribute.isStringAttribute())
431 const ::llvm::AttributeList & attributeList,
432 const size_t numParameters,
435 auto returnAttributes =
convert_attributes(attributeList.getRetAttrs(), typeConverter);
436 auto functionAttributes =
convert_attributes(attributeList.getFnAttrs(), typeConverter);
438 std::vector<AttributeSet> parameterAttributes;
439 for (
size_t n = 0; n < numParameters; n++)
441 parameterAttributes.emplace_back(
446 std::move(functionAttributes),
447 std::move(returnAttributes),
448 std::move(parameterAttributes));
451static const Variable *
453 ::llvm::Constant * c,
454 std::vector<std::unique_ptr<ThreeAddressCode>> & tacs,
457 JLM_ASSERT(c->getValueID() == ::llvm::Value::ConstantIntVal);
458 const auto constant = ::llvm::cast<const ::llvm::ConstantInt>(c);
464 return tacs.back()->result(0);
467static inline const Variable *
469 ::llvm::Constant * c,
470 std::vector<std::unique_ptr<llvm::ThreeAddressCode>> & tacs,
473 JLM_ASSERT(c->getValueID() == ::llvm::Value::UndefValueVal);
478 return tacs.back()->result(0);
481static const Variable *
483 ::llvm::Constant * constant,
484 std::vector<std::unique_ptr<llvm::ThreeAddressCode>> & tacs,
487 JLM_ASSERT(constant->getValueID() == ::llvm::Value::ConstantExprVal);
488 auto c = ::llvm::cast<::llvm::ConstantExpr>(constant);
500 auto instruction = c->getAsInstruction();
502 instruction->dropAllReferences();
506static const Variable *
508 ::llvm::Constant * constant,
509 std::vector<std::unique_ptr<llvm::ThreeAddressCode>> & tacs,
512 JLM_ASSERT(constant->getValueID() == ::llvm::Value::ConstantFPVal);
513 auto c = ::llvm::cast<::llvm::ConstantFP>(constant);
518 return tacs.back()->result(0);
521static const Variable *
523 ::llvm::Constant * c,
524 std::vector<std::unique_ptr<llvm::ThreeAddressCode>> & tacs,
527 JLM_ASSERT(c->getValueID() == ::llvm::Value::GlobalVariableVal);
531static const Variable *
533 ::llvm::Constant * constant,
534 std::vector<std::unique_ptr<llvm::ThreeAddressCode>> & tacs,
537 JLM_ASSERT(::llvm::dyn_cast<const ::llvm::ConstantPointerNull>(constant));
538 auto & c = *::llvm::cast<const ::llvm::ConstantPointerNull>(constant);
543 return tacs.back()->result(0);
546static const Variable *
548 ::llvm::Constant * constant,
549 std::vector<std::unique_ptr<llvm::ThreeAddressCode>> &,
552 JLM_ASSERT(constant->getValueID() == ::llvm::Value::BlockAddressVal);
557static const Variable *
559 ::llvm::Constant * c,
560 std::vector<std::unique_ptr<llvm::ThreeAddressCode>> & tacs,
563 JLM_ASSERT(c->getValueID() == ::llvm::Value::ConstantAggregateZeroVal);
568 return tacs.back()->result(0);
571static const Variable *
573 ::llvm::Constant * c,
574 std::vector<std::unique_ptr<llvm::ThreeAddressCode>> & tacs,
577 JLM_ASSERT(c->getValueID() == ::llvm::Value::ConstantArrayVal);
579 std::vector<const Variable *> elements;
580 for (
size_t n = 0; n < c->getNumOperands(); n++)
582 auto operand = c->getOperand(n);
583 JLM_ASSERT(::llvm::dyn_cast<const ::llvm::Constant>(operand));
584 auto constant = ::llvm::cast<::llvm::Constant>(operand);
590 return tacs.back()->result(0);
593static const Variable *
595 ::llvm::Constant * constant,
596 std::vector<std::unique_ptr<llvm::ThreeAddressCode>> & tacs,
599 JLM_ASSERT(constant->getValueID() == ::llvm::Value::ConstantDataArrayVal);
600 const auto & c = *::llvm::cast<const ::llvm::ConstantDataArray>(constant);
602 std::vector<const Variable *> elements;
603 for (
size_t n = 0; n < c.getNumElements(); n++)
604 elements.push_back(
ConvertConstant(c.getElementAsConstant(n), tacs, ctx));
608 return tacs.back()->result(0);
611static const Variable *
613 ::llvm::Constant * constant,
614 std::vector<std::unique_ptr<llvm::ThreeAddressCode>> & tacs,
617 JLM_ASSERT(constant->getValueID() == ::llvm::Value::ConstantDataVectorVal);
618 auto c = ::llvm::cast<const ::llvm::ConstantDataVector>(constant);
620 std::vector<const Variable *> elements;
621 for (
size_t n = 0; n < c->getNumElements(); n++)
622 elements.push_back(
ConvertConstant(c->getElementAsConstant(n), tacs, ctx));
626 return tacs.back()->result(0);
629static const Variable *
631 ::llvm::Constant * c,
632 std::vector<std::unique_ptr<llvm::ThreeAddressCode>> & tacs,
635 JLM_ASSERT(c->getValueID() == ::llvm::Value::ConstantStructVal);
637 std::vector<const Variable *> elements;
638 for (
size_t n = 0; n < c->getNumOperands(); n++)
639 elements.push_back(
ConvertConstant(c->getAggregateElement(n), tacs, ctx));
644 return tacs.back()->result(0);
647static const Variable *
649 ::llvm::Constant * c,
650 std::vector<std::unique_ptr<llvm::ThreeAddressCode>> & tacs,
653 JLM_ASSERT(c->getValueID() == ::llvm::Value::ConstantVectorVal);
655 std::vector<const Variable *> elements;
656 for (
size_t n = 0; n < c->getNumOperands(); n++)
657 elements.push_back(
ConvertConstant(c->getAggregateElement(n), tacs, ctx));
662 return tacs.back()->result(0);
665static inline const Variable *
667 ::llvm::Constant * constant,
668 std::vector<std::unique_ptr<llvm::ThreeAddressCode>> &,
671 JLM_ASSERT(constant->getValueID() == ::llvm::Value::GlobalAliasVal);
676static inline const Variable *
679 JLM_ASSERT(c->getValueID() == ::llvm::Value::FunctionVal);
683static const Variable *
685 ::llvm::PoisonValue * poisonValue,
692 return threeAddressCodeVector.back()->result(0);
696static const Variable *
698 ::llvm::Constant * constant,
703 return ConvertConstant(::llvm::cast<T>(constant), threeAddressCodeVector, context);
706static const Variable *
708 ::llvm::Constant * c,
709 std::vector<std::unique_ptr<llvm::ThreeAddressCode>> & tacs,
712 static std::unordered_map<
714 const Variable * (*)(::llvm::Constant *,
715 std::vector<std::unique_ptr<llvm::ThreeAddressCode>> &,
731 { ::llvm::Value::PoisonValueVal, ConvertConstant<::llvm::PoisonValue> },
734 if (constantMap.find(c->getValueID()) != constantMap.end())
735 return constantMap[c->getValueID()](c, tacs, ctx);
740static std::vector<std::unique_ptr<llvm::ThreeAddressCode>>
743 std::vector<std::unique_ptr<llvm::ThreeAddressCode>> tacs;
748static inline const Variable *
751 JLM_ASSERT(instruction->getOpcode() == ::llvm::Instruction::Ret);
752 auto i = ::llvm::cast<::llvm::ReturnInst>(instruction);
754 auto bb = ctx.
get(i->getParent());
756 if (!i->getReturnValue())
759 auto value =
ConvertValue(i->getReturnValue(), tacs, ctx);
765static const Variable *
768 JLM_ASSERT(instruction->getOpcode() == ::llvm::Instruction::Br);
769 auto i = ::llvm::cast<::llvm::BranchInst>(instruction);
770 auto bb = ctx.
get(i->getParent());
774 if (i->isUnconditional())
776 bb->add_outedge(ctx.
get(i->getSuccessor(0)));
780 bb->add_outedge(ctx.
get(i->getSuccessor(1)));
781 bb->add_outedge(ctx.
get(i->getSuccessor(0)));
784 auto nbits = i->getCondition()->getType()->getIntegerBitWidth();
793static const Variable *
796 auto jlmSwitchBasicBlock = ctx.
get(switchInstruction->getParent());
798 JLM_ASSERT(jlmSwitchBasicBlock->NumOutEdges() == 0);
799 std::unordered_map<uint64_t, uint64_t> matchMapping;
800 std::unordered_map<::llvm::BasicBlock *, ControlFlowGraphEdge *> outEdgeMapping;
801 for (
auto caseIt = switchInstruction->case_begin(); caseIt != switchInstruction->case_end();
804 JLM_ASSERT(caseIt != switchInstruction->case_default());
805 auto llvmCaseBasicBlock = caseIt->getCaseSuccessor();
807 if (
auto outEdgeIt = outEdgeMapping.find(llvmCaseBasicBlock); outEdgeIt != outEdgeMapping.end())
811 matchMapping[caseIt->getCaseValue()->getZExtValue()] = outEdgeIt->second->index();
815 auto jlmCaseBasicBlock = ctx.
get(llvmCaseBasicBlock);
816 auto edge = jlmSwitchBasicBlock->
add_outedge(jlmCaseBasicBlock);
817 outEdgeMapping[llvmCaseBasicBlock] = edge;
818 matchMapping[caseIt->getCaseValue()->getZExtValue()] = edge->
index();
822 auto jlmDefaultBasicBlock = ctx.
get(switchInstruction->case_default()->getCaseSuccessor());
823 auto defaultEdge = jlmSwitchBasicBlock->
add_outedge(jlmDefaultBasicBlock);
825 auto c =
ConvertValue(switchInstruction->getCondition(), tacs, ctx);
826 auto numBits = switchInstruction->getCondition()->getType()->getIntegerBitWidth();
827 auto op = std::make_unique<rvsdg::MatchOperation>(
830 defaultEdge->index(),
831 jlmSwitchBasicBlock->NumOutEdges());
839static inline const Variable *
842 JLM_ASSERT(i->getOpcode() == ::llvm::Instruction::Unreachable);
843 auto bb = ctx.
get(i->getParent());
848static std::unique_ptr<rvsdg::BinaryOperation>
853 case ::llvm::CmpInst::ICMP_SLT:
854 return std::make_unique<IntegerSltOperation>(numBits);
855 case ::llvm::CmpInst::ICMP_ULT:
856 return std::make_unique<IntegerUltOperation>(numBits);
857 case ::llvm::CmpInst::ICMP_SLE:
858 return std::make_unique<IntegerSleOperation>(numBits);
859 case ::llvm::CmpInst::ICMP_ULE:
860 return std::make_unique<IntegerUleOperation>(numBits);
861 case ::llvm::CmpInst::ICMP_EQ:
862 return std::make_unique<IntegerEqOperation>(numBits);
863 case ::llvm::CmpInst::ICMP_NE:
864 return std::make_unique<IntegerNeOperation>(numBits);
865 case ::llvm::CmpInst::ICMP_SGE:
866 return std::make_unique<IntegerSgeOperation>(numBits);
867 case ::llvm::CmpInst::ICMP_UGE:
868 return std::make_unique<IntegerUgeOperation>(numBits);
869 case ::llvm::CmpInst::ICMP_SGT:
870 return std::make_unique<IntegerSgtOperation>(numBits);
871 case ::llvm::CmpInst::ICMP_UGT:
872 return std::make_unique<IntegerUgtOperation>(numBits);
874 JLM_UNREACHABLE(
"ConvertIntegerIcmpPredicate: Unsupported icmp predicate.");
878static std::unique_ptr<rvsdg::BinaryOperation>
885static const Variable *
888 const auto predicate = instruction->getPredicate();
889 const auto operandType = instruction->getOperand(0)->getType();
890 auto op1 =
ConvertValue(instruction->getOperand(0), tacs, ctx);
891 auto op2 =
ConvertValue(instruction->getOperand(1), tacs, ctx);
893 std::unique_ptr<rvsdg::BinaryOperation> operation;
894 if (operandType->isVectorTy() && operandType->getScalarType()->isIntegerTy())
899 else if (operandType->isVectorTy() && operandType->getScalarType()->isPointerTy())
903 else if (operandType->isIntegerTy())
907 else if (operandType->isPointerTy())
916 if (operandType->isVectorTy())
926 return tacs.back()->result(0);
929static const Variable *
932 JLM_ASSERT(instruction->getOpcode() == ::llvm::Instruction::FCmp);
934 auto i = ::llvm::cast<const ::llvm::FCmpInst>(instruction);
935 auto t = i->getOperand(0)->getType();
937 static std::unordered_map<::llvm::CmpInst::Predicate, llvm::fpcmp> map(
955 auto type = typeConverter.ConvertLlvmType(*i->getType());
960 JLM_ASSERT(map.find(i->getPredicate()) != map.end());
961 auto fptype = t->isVectorTy() ? t->getScalarType() : t;
962 auto operation = std::make_unique<FCmpOperation>(
963 map[i->getPredicate()],
964 typeConverter.ExtractFloatingPointSize(*fptype));
971 return tacs.back()->result(0);
974static const Variable *
977 auto ioBarrierOperation = std::make_unique<IOBarrierOperation>(operand->
Type());
980 return tacs.back()->result(0);
983static inline const Variable *
986 JLM_ASSERT(i->getOpcode() == ::llvm::Instruction::Load);
987 auto instruction =
static_cast<::llvm::LoadInst *
>(i);
989 auto alignment = instruction->getAlign().value();
990 auto address =
ConvertValue(instruction->getPointerOperand(), tacs, ctx);
999 if (instruction->isVolatile())
1007 tacs.push_back(std::move(loadVolatileTac));
1009 loadedValue = tacs.back()->result(0);
1010 ioState = tacs.back()->result(1);
1011 memoryState = tacs.back()->result(2);
1018 tacs.push_back(std::move(loadTac));
1019 loadedValue = tacs.back()->result(0);
1020 memoryState = tacs.back()->result(1);
1032static inline const Variable *
1035 JLM_ASSERT(i->getOpcode() == ::llvm::Instruction::Store);
1036 auto instruction =
static_cast<::llvm::StoreInst *
>(i);
1038 auto alignment = instruction->getAlign().value();
1039 auto address =
ConvertValue(instruction->getPointerOperand(), tacs, ctx);
1040 auto value =
ConvertValue(instruction->getValueOperand(), tacs, ctx);
1047 if (instruction->isVolatile())
1055 tacs.push_back(std::move(storeVolatileTac));
1056 ioState = tacs.back()->result(0);
1057 memoryState = tacs.back()->result(1);
1064 tacs.push_back(std::move(storeTac));
1065 memoryState = tacs.back()->result(0);
1077static const Variable *
1086 return tacs.back()->result(0);
1089static const Variable *
1092 JLM_ASSERT(::llvm::dyn_cast<const ::llvm::GetElementPtrInst>(inst));
1094 auto i = ::llvm::cast<::llvm::GetElementPtrInst>(inst);
1096 std::vector<const Variable *> indices;
1097 auto base =
ConvertValue(i->getPointerOperand(), tacs, ctx);
1098 for (
auto it = i->idx_begin(); it != i->idx_end(); it++)
1101 auto pointeeType = typeConverter.ConvertLlvmType(*i->getSourceElementType());
1105 return tacs.back()->result(0);
1108static const Variable *
1110 const ::llvm::CallInst & instruction,
1115 const auto globalIOState = context.
iostate();
1117 const auto size =
ConvertValue(instruction.getArgOperand(0), threeAddressCodes, context);
1120 const auto mallocAddress = threeAddressCodes.back()->result(0);
1121 const auto mallocIOState = threeAddressCodes.back()->result(1);
1122 auto mallocMemoryState = threeAddressCodes.back()->result(2);
1126 threeAddressCodes.push_back(
1128 threeAddressCodes.push_back(
1131 return mallocAddress;
1134static const Variable *
1136 const ::llvm::CallInst & instruction,
1140 const auto ioState = context.
iostate();
1143 const auto pointer =
ConvertValue(instruction.getArgOperand(0), threeAddressCodes, context);
1146 const auto & freeThreeAddressCode = *threeAddressCodes.back().get();
1148 threeAddressCodes.push_back(
1166 const auto constant = ::llvm::dyn_cast<const ::llvm::ConstantInt>(&value);
1167 JLM_ASSERT(constant !=
nullptr && constant->getType()->getIntegerBitWidth() == 1);
1169 const auto apInt = constant->getValue();
1172 return apInt.isOne();
1175static const Variable *
1177 const ::llvm::IntrinsicInst * instruction,
1182 instruction->getIntrinsicID() == ::llvm::Intrinsic::memcpy
1183 || instruction->getIntrinsicID() == ::llvm::Intrinsic::memcpy_inline
1184 || instruction->getIntrinsicID() == ::llvm::Intrinsic::memcpy_element_unordered_atomic);
1186 if (instruction->getIntrinsicID() == ::llvm::Intrinsic::memcpy_inline)
1187 throw std::logic_error(
"Unhandled memcpy_inline intrinsic.");
1188 if (instruction->getIntrinsicID() == ::llvm::Intrinsic::memcpy_element_unordered_atomic)
1189 throw std::logic_error(
"Unhandled memcpy_element_unordered_atomic intrinsic.");
1191 const auto ioState = context.
iostate();
1194 const auto destination =
ConvertValue(instruction->getArgOperand(0), threeAddressCodes, context);
1195 const auto source =
ConvertValue(instruction->getArgOperand(1), threeAddressCodes, context);
1196 const auto length =
ConvertValue(instruction->getArgOperand(2), threeAddressCodes, context);
1198 if (
IsVolatile(*instruction->getArgOperand(3)))
1206 const auto & memCpyVolatileTac = *threeAddressCodes.back();
1208 threeAddressCodes.push_back(
1213 threeAddressCodes.push_back(
1215 threeAddressCodes.push_back(
1222static const Variable *
1224 const ::llvm::IntrinsicInst & instruction,
1229 instruction.getIntrinsicID() == ::llvm::Intrinsic::memset
1230 || instruction.getIntrinsicID() == ::llvm::Intrinsic::memset_inline
1231 || instruction.getIntrinsicID() == ::llvm::Intrinsic::memset_element_unordered_atomic);
1233 if (instruction.getIntrinsicID() == ::llvm::Intrinsic::memset_inline)
1234 throw std::logic_error(
"Unhandled memset_inline intrinsic.");
1235 if (instruction.getIntrinsicID() == ::llvm::Intrinsic::memset_element_unordered_atomic)
1236 throw std::logic_error(
"Unhandled memset_element_unordered_atomic intrinsic.");
1240 const auto destination =
ConvertValue(instruction.getArgOperand(0), threeAddressCodes, context);
1241 const auto value =
ConvertValue(instruction.getArgOperand(1), threeAddressCodes, context);
1242 const auto length =
ConvertValue(instruction.getArgOperand(2), threeAddressCodes, context);
1244 if (
IsVolatile(*instruction.getArgOperand(3)))
1246 throw std::logic_error(
"Unhandled volatile memset intrinsic.");
1250 threeAddressCodes.push_back(
1252 threeAddressCodes.push_back(
1259static const Variable *
1261 const ::llvm::IntrinsicInst & instruction,
1266 instruction.getIntrinsicID() == ::llvm::Intrinsic::memmove
1267 || instruction.getIntrinsicID() == ::llvm::Intrinsic::memmove_element_unordered_atomic);
1269 if (instruction.getIntrinsicID() == ::llvm::Intrinsic::memmove_element_unordered_atomic)
1270 throw std::logic_error(
"Unhandled memmove_element_unordered_atomic intrinsic.");
1274 const auto destOperand =
ConvertValue(instruction.getArgOperand(0), threeAddressCodes, context);
1275 const auto srcOperand =
ConvertValue(instruction.getArgOperand(1), threeAddressCodes, context);
1276 const auto lengthOperand =
ConvertValue(instruction.getArgOperand(2), threeAddressCodes, context);
1278 if (
IsVolatile(*instruction.getArgOperand(3)))
1280 throw std::logic_error(
"Unhandled volatile memmove intrinsic.");
1288 threeAddressCodes.push_back(
1297 const auto function = callInstruction.getCalledFunction();
1298 return function && function->getName() ==
"malloc";
1304 const auto function = callInstruction.getCalledFunction();
1305 return function && function->getName() ==
"free";
1308static const Variable *
1311 const auto multiplier =
ConvertValue(instruction.getArgOperand(0), tacs, ctx);
1312 const auto multiplicand =
ConvertValue(instruction.getArgOperand(1), tacs, ctx);
1313 const auto summand =
ConvertValue(instruction.getArgOperand(2), tacs, ctx);
1316 return tacs.back()->result(0);
1319static const Variable *
1322 const auto operand =
ConvertValue(instruction.getArgOperand(0), tacs, context);
1325 return tacs.back()->result(0);
1328static const Variable *
1331 const auto operand =
ConvertValue(instruction.getArgOperand(0), tacs, context);
1334 return tacs.back()->result(0);
1337static const Variable *
1340 const auto operand =
ConvertValue(instruction.getArgOperand(0), tacs, context);
1343 return tacs.back()->result(0);
1346static const Variable *
1349 const auto operand =
ConvertValue(instruction.getArgOperand(0), tacs, context);
1352 return tacs.back()->result(0);
1355static const Variable *
1358 const auto operand =
ConvertValue(instruction.getArgOperand(0), tacs, context);
1361 return tacs.back()->result(0);
1364static const Variable *
1367 const auto operand1 =
ConvertValue(instruction.getArgOperand(0), tacs, context);
1368 const auto operand2 =
ConvertValue(instruction.getArgOperand(1), tacs, context);
1369 const auto operand3 =
ConvertValue(instruction.getArgOperand(2), tacs, context);
1372 return tacs.back()->result(0);
1375static const Variable *
1378 const auto operand1 =
ConvertValue(instruction.getArgOperand(0), tacs, context);
1379 const auto operand2 =
ConvertValue(instruction.getArgOperand(1), tacs, context);
1382 return tacs.back()->result(0);
1385static const Variable *
1388 const auto operand1 =
ConvertValue(instruction.getArgOperand(0), tacs, context);
1389 const auto operand2 =
ConvertValue(instruction.getArgOperand(1), tacs, context);
1392 return tacs.back()->result(0);
1395static const Variable *
1398 const auto operand1 =
ConvertValue(instruction.getArgOperand(0), tacs, context);
1399 const auto operand2 =
ConvertValue(instruction.getArgOperand(1), tacs, context);
1402 return tacs.back()->result(0);
1405static const Variable *
1408 const auto operand1 =
ConvertValue(instruction.getArgOperand(0), tacs, context);
1409 const auto operand2 =
ConvertValue(instruction.getArgOperand(1), tacs, context);
1412 return tacs.back()->result(0);
1415static const Variable *
1417 const ::llvm::CallInst & instruction,
1421 const auto operand1 =
ConvertValue(instruction.getArgOperand(0), tacs, context);
1422 const auto operand2 =
ConvertValue(instruction.getArgOperand(1), tacs, context);
1425 return tacs.back()->result(0);
1428static const Variable *
1430 const ::llvm::CallInst & instruction,
1434 const auto ptrOperand =
ConvertValue(instruction.getArgOperand(0), tacs, context);
1435 const auto maskOperand =
ConvertValue(instruction.getArgOperand(1), tacs, context);
1438 return tacs.back()->result(0);
1441static const Variable *
1444 const auto operand =
ConvertValue(instruction.getArgOperand(0), tacs, context);
1447 return tacs.back()->result(0);
1450static const Variable *
1453 const auto operand1 =
ConvertValue(instruction.getArgOperand(0), tacs, context);
1454 const auto operand2 =
ConvertValue(instruction.getArgOperand(1), tacs, context);
1457 return tacs.back()->result(0);
1460static const Variable *
1463 const auto operand =
ConvertValue(instruction.getArgOperand(0), tacs, context);
1466 return tacs.back()->result(0);
1469static const Variable *
1472 const auto operand1 =
ConvertValue(instruction.getArgOperand(0), tacs, context);
1473 const auto operand2 =
ConvertValue(instruction.getArgOperand(1), tacs, context);
1476 return tacs.back()->result(0);
1479static const Variable *
1482 const auto operand1 =
ConvertValue(instruction.getArgOperand(0), tacs, context);
1483 const auto operand2 =
ConvertValue(instruction.getArgOperand(1), tacs, context);
1486 return tacs.back()->result(0);
1489static const Variable *
1492 const auto operand =
ConvertValue(instruction.getArgOperand(0), tacs, context);
1495 return tacs.back()->result(0);
1498static const Variable *
1500 const ::llvm::CallInst & instruction,
1504 const auto operand =
ConvertValue(instruction.getArgOperand(0), tacs, context);
1507 return tacs.back()->result(0);
1510static const Variable *
1512 const ::llvm::CallInst & instruction,
1516 const auto operand1 =
ConvertValue(instruction.getArgOperand(0), tacs, context);
1517 const auto operand2 =
ConvertValue(instruction.getArgOperand(1), tacs, context);
1520 return tacs.back()->result(0);
1523static const Variable *
1525 const ::llvm::CallInst & instruction,
1529 const auto operand1 =
ConvertValue(instruction.getArgOperand(0), tacs, context);
1530 const auto operand2 =
ConvertValue(instruction.getArgOperand(1), tacs, context);
1533 return tacs.back()->result(0);
1536static const Variable *
1538 const ::llvm::CallInst & instruction,
1542 const auto operand1 =
ConvertValue(instruction.getArgOperand(0), tacs, context);
1543 const auto operand2 =
ConvertValue(instruction.getArgOperand(1), tacs, context);
1546 return tacs.back()->result(0);
1549static const Variable *
1551 const ::llvm::CallInst & instruction,
1555 const auto operand1 =
ConvertValue(instruction.getArgOperand(0), tacs, context);
1556 const auto operand2 =
ConvertValue(instruction.getArgOperand(1), tacs, context);
1559 return tacs.back()->result(0);
1562static const Variable *
1564 const ::llvm::CallInst & instruction,
1568 const auto operand1 =
ConvertValue(instruction.getArgOperand(0), tacs, context);
1569 const auto operand2 =
ConvertValue(instruction.getArgOperand(1), tacs, context);
1572 return tacs.back()->result(0);
1575static const Variable *
1577 const ::llvm::CallInst & instruction,
1581 const auto operand1 =
ConvertValue(instruction.getArgOperand(0), tacs, context);
1582 const auto operand2 =
ConvertValue(instruction.getArgOperand(1), tacs, context);
1585 return tacs.back()->result(0);
1588std::vector<const Variable *>
1590 const ::llvm::CallInst & callInstruction,
1594 const auto functionType = callInstruction.getFunctionType();
1596 std::vector<const Variable *>
arguments;
1597 for (
size_t n = 0; n < functionType->getNumParams(); n++)
1600 if (functionType->isVarArg())
1602 std::vector<const Variable *> variableArguments;
1603 for (
size_t n = functionType->getNumParams(); n < callInstruction.getNumOperands() - 1; n++)
1604 variableArguments.push_back(
1605 ConvertValue(callInstruction.getArgOperand(n), threeAddressCodes, context));
1608 arguments.push_back(threeAddressCodes.back()->result(0));
1617static const Variable *
1619 const ::llvm::CallInst & callInstruction,
1623 const auto functionType = callInstruction.getFunctionType();
1629 callInstruction.getAttributes(),
1630 callInstruction.arg_size(),
1640 if (is<PointerType>(*callee->
Type()))
1643 std::make_unique<PointerToFunctionOperation>(convertedFunctionType),
1645 callee = callee_cast->result(0);
1646 threeAddressCodes.push_back(std::move(callee_cast));
1648 else if (
auto fntype = std::dynamic_pointer_cast<const rvsdg::FunctionType>(callee->
Type()))
1653 if (*convertedFunctionType != *fntype)
1658 std::make_unique<FunctionToPointerOperation>(fntype),
1661 std::make_unique<PointerToFunctionOperation>(convertedFunctionType),
1662 { ptrCast->result(0) });
1663 callee = fnCast->result(0);
1664 threeAddressCodes.push_back(std::move(ptrCast));
1665 threeAddressCodes.push_back(std::move(fnCast));
1670 throw std::runtime_error(
"Unexpected callee type: " + callee->
Type()->debug_string());
1675 convertedFunctionType,
1677 std::move(attributes),
1680 const auto result = call->result(0);
1681 const auto ioState = call->result(call->nresults() - 2);
1682 const auto memoryState = call->result(call->nresults() - 1);
1684 threeAddressCodes.push_back(std::move(call));
1700 switch (intrinsicId)
1705 case ::llvm::Intrinsic::assume:
1706 case ::llvm::Intrinsic::expect:
1707 case ::llvm::Intrinsic::prefetch:
1711 case ::llvm::Intrinsic::lifetime_start:
1712 case ::llvm::Intrinsic::lifetime_end:
1715 case ::llvm::Intrinsic::experimental_noalias_scope_decl:
1723static const Variable *
1725 const ::llvm::IntrinsicInst & intrinsicInstruction,
1729 switch (
const auto intrinsicId = intrinsicInstruction.getIntrinsicID())
1731 case ::llvm::Intrinsic::abs:
1733 case ::llvm::Intrinsic::assume:
1738 case ::llvm::Intrinsic::bswap:
1740 case ::llvm::Intrinsic::ceil:
1742 case ::llvm::Intrinsic::copysign:
1744 case ::llvm::Intrinsic::ctlz:
1746 case ::llvm::Intrinsic::cttz:
1748 case ::llvm::Intrinsic::ctpop:
1750 case ::llvm::Intrinsic::expect:
1753 return ConvertValue(intrinsicInstruction.getArgOperand(0), threeAddressCodes, context);
1755 case ::llvm::Intrinsic::experimental_noalias_scope_decl:
1760 case ::llvm::Intrinsic::fabs:
1762 case ::llvm::Intrinsic::floor:
1764 case ::llvm::Intrinsic::fmuladd:
1766 case ::llvm::Intrinsic::fshl:
1768 case ::llvm::Intrinsic::is_constant:
1770 case ::llvm::Intrinsic::is_fpclass:
1772 case ::llvm::Intrinsic::lifetime_start:
1773 case ::llvm::Intrinsic::lifetime_end:
1778 case ::llvm::Intrinsic::memcpy:
1779 case ::llvm::Intrinsic::memcpy_inline:
1780 case ::llvm::Intrinsic::memcpy_element_unordered_atomic:
1782 case ::llvm::Intrinsic::memmove:
1783 case ::llvm::Intrinsic::memmove_element_unordered_atomic:
1785 case ::llvm::Intrinsic::memset:
1786 case ::llvm::Intrinsic::memset_inline:
1787 case ::llvm::Intrinsic::memset_element_unordered_atomic:
1789 case ::llvm::Intrinsic::prefetch:
1794 case ::llvm::Intrinsic::ptrmask:
1796 case ::llvm::Intrinsic::rint:
1798 case ::llvm::Intrinsic::round:
1800 case ::llvm::Intrinsic::sadd_with_overflow:
1802 case ::llvm::Intrinsic::smax:
1804 case ::llvm::Intrinsic::smul_with_overflow:
1806 case ::llvm::Intrinsic::smin:
1808 case ::llvm::Intrinsic::ssub_with_overflow:
1810 case ::llvm::Intrinsic::trunc:
1812 case ::llvm::Intrinsic::uadd_with_overflow:
1814 case ::llvm::Intrinsic::umax:
1816 case ::llvm::Intrinsic::umin:
1818 case ::llvm::Intrinsic::umul_with_overflow:
1823 return createCall(intrinsicInstruction, threeAddressCodes, context);
1828static const Variable *
1830 const ::llvm::CallInst & callInstruction,
1834 if (
const auto intrinsicInstruction = ::llvm::dyn_cast<::llvm::IntrinsicInst>(&callInstruction))
1843 return createCall(callInstruction, threeAddressCodes, context);
1846static inline const Variable *
1849 JLM_ASSERT(i->getOpcode() == ::llvm::Instruction::Select);
1850 auto instruction =
static_cast<::llvm::SelectInst *
>(i);
1852 auto p =
ConvertValue(instruction->getCondition(), tacs, ctx);
1853 auto t =
ConvertValue(instruction->getTrueValue(), tacs, ctx);
1854 auto f =
ConvertValue(instruction->getFalseValue(), tacs, ctx);
1856 if (i->getType()->isVectorTy())
1861 return tacs.back()->result(0);
1864static std::unique_ptr<rvsdg::BinaryOperation>
1866 const ::llvm::Instruction::BinaryOps binaryOperation,
1867 std::size_t numBits)
1869 switch (binaryOperation)
1871 case ::llvm::Instruction::Add:
1872 return std::make_unique<IntegerAddOperation>(numBits);
1873 case ::llvm::Instruction::And:
1874 return std::make_unique<IntegerAndOperation>(numBits);
1875 case ::llvm::Instruction::AShr:
1876 return std::make_unique<IntegerAShrOperation>(numBits);
1877 case ::llvm::Instruction::LShr:
1878 return std::make_unique<IntegerLShrOperation>(numBits);
1879 case ::llvm::Instruction::Mul:
1880 return std::make_unique<IntegerMulOperation>(numBits);
1881 case ::llvm::Instruction::Or:
1882 return std::make_unique<IntegerOrOperation>(numBits);
1883 case ::llvm::Instruction::SDiv:
1884 return std::make_unique<IntegerSDivOperation>(numBits);
1885 case ::llvm::Instruction::Shl:
1886 return std::make_unique<IntegerShlOperation>(numBits);
1887 case ::llvm::Instruction::SRem:
1888 return std::make_unique<IntegerSRemOperation>(numBits);
1889 case ::llvm::Instruction::Sub:
1890 return std::make_unique<IntegerSubOperation>(numBits);
1891 case ::llvm::Instruction::UDiv:
1892 return std::make_unique<IntegerUDivOperation>(numBits);
1893 case ::llvm::Instruction::URem:
1894 return std::make_unique<IntegerURemOperation>(numBits);
1895 case ::llvm::Instruction::Xor:
1896 return std::make_unique<IntegerXorOperation>(numBits);
1898 JLM_UNREACHABLE(
"ConvertIntegerBinaryOperation: Unsupported integer binary operation");
1902static std::unique_ptr<rvsdg::BinaryOperation>
1904 const ::llvm::Instruction::BinaryOps binaryOperation,
1905 fpsize floatingPointSize)
1907 switch (binaryOperation)
1909 case ::llvm::Instruction::FAdd:
1910 return std::make_unique<FBinaryOperation>(
fpop::add, floatingPointSize);
1911 case ::llvm::Instruction::FSub:
1912 return std::make_unique<FBinaryOperation>(
fpop::sub, floatingPointSize);
1913 case ::llvm::Instruction::FMul:
1914 return std::make_unique<FBinaryOperation>(
fpop::mul, floatingPointSize);
1915 case ::llvm::Instruction::FDiv:
1916 return std::make_unique<FBinaryOperation>(
fpop::div, floatingPointSize);
1917 case ::llvm::Instruction::FRem:
1918 return std::make_unique<FBinaryOperation>(
fpop::mod, floatingPointSize);
1920 JLM_UNREACHABLE(
"ConvertFloatingPointBinaryOperation: Unsupported binary operation");
1924static const Variable *
1927 const auto llvmType = instruction->getType();
1929 const auto opcode = instruction->getOpcode();
1931 std::unique_ptr<rvsdg::BinaryOperation> operation;
1932 if (llvmType->isVectorTy() && llvmType->getScalarType()->isIntegerTy())
1934 const auto numBits = llvmType->getScalarType()->getIntegerBitWidth();
1937 else if (llvmType->isVectorTy() && llvmType->getScalarType()->isFloatingPointTy())
1939 const auto size = typeConverter.ExtractFloatingPointSize(*llvmType->getScalarType());
1942 else if (llvmType->isIntegerTy())
1946 else if (llvmType->isFloatingPointTy())
1948 const auto size = typeConverter.ExtractFloatingPointSize(*llvmType);
1953 JLM_ASSERT(
"convert: Unhandled binary operation type.");
1956 const auto jlmType = typeConverter.ConvertLlvmType(*llvmType);
1957 auto operand1 =
ConvertValue(instruction->getOperand(0), tacs, ctx);
1958 auto operand2 =
ConvertValue(instruction->getOperand(1), tacs, ctx);
1960 if (instruction->getOpcode() == ::llvm::Instruction::SDiv
1961 || instruction->getOpcode() == ::llvm::Instruction::UDiv
1962 || instruction->getOpcode() == ::llvm::Instruction::SRem
1963 || instruction->getOpcode() == ::llvm::Instruction::URem)
1968 if (llvmType->isVectorTy())
1977 return tacs.back()->result(0);
1980static inline const Variable *
1983 JLM_ASSERT(instruction->getOpcode() == ::llvm::Instruction::Alloca);
1984 auto i =
static_cast<::llvm::AllocaInst *
>(instruction);
1987 auto size =
ConvertValue(i->getArraySize(), tacs, ctx);
1989 auto alignment = i->getAlign().value();
1992 auto result = tacs.back()->result(0);
1993 auto astate = tacs.back()->result(1);
2001static const Variable *
2004 JLM_ASSERT(i->getOpcode() == ::llvm::Instruction::ExtractValue);
2005 auto ev = ::llvm::dyn_cast<::llvm::ExtractValueInst>(i);
2010 return tacs.back()->result(0);
2013static const Variable *
2015 const ::llvm::InsertValueInst & instruction,
2019 const auto aggregateOperand =
ConvertValue(instruction.getOperand(0), tacs, context);
2020 const auto valueOperand =
ConvertValue(instruction.getOperand(1), tacs, context);
2025 return tacs.back()->result(0);
2028static inline const Variable *
2031 JLM_ASSERT(i->getOpcode() == ::llvm::Instruction::ExtractElement);
2033 auto vector =
ConvertValue(i->getOperand(0), tacs, ctx);
2034 auto index =
ConvertValue(i->getOperand(1), tacs, ctx);
2037 return tacs.back()->result(0);
2040static const Variable *
2046 std::vector<int> mask;
2047 for (
auto & element : i->getShuffleMask())
2048 mask.push_back(element);
2052 return tacs.back()->result(0);
2055static const Variable *
2058 JLM_ASSERT(i->getOpcode() == ::llvm::Instruction::InsertElement);
2060 auto vector =
ConvertValue(i->getOperand(0), tacs, ctx);
2061 auto value =
ConvertValue(i->getOperand(1), tacs, ctx);
2062 auto index =
ConvertValue(i->getOperand(2), tacs, ctx);
2065 return tacs.back()->result(0);
2068static const Variable *
2071 JLM_ASSERT(i->getOpcode() == ::llvm::Instruction::Freeze);
2073 auto operand =
ConvertValue(i->getOperand(0), tacs, ctx);
2076 return tacs.back()->result(0);
2079static const Variable *
2082 JLM_ASSERT(unaryOperator->getOpcode() == ::llvm::Instruction::FNeg);
2085 auto type = unaryOperator->getType();
2086 auto scalarType = typeConverter.
ConvertLlvmType(*type->getScalarType());
2087 auto operand =
ConvertValue(unaryOperator->getOperand(0), threeAddressCodeVector, ctx);
2089 if (type->isVectorTy())
2091 auto vectorType = typeConverter.ConvertLlvmType(*type);
2093 FNegOperation(std::static_pointer_cast<const FloatingPointType>(scalarType)),
2102 return threeAddressCodeVector.back()->result(0);
2106static std::unique_ptr<rvsdg::SimpleOperation>
2107create_unop(std::shared_ptr<const rvsdg::Type> st, std::shared_ptr<const rvsdg::Type> dt)
2109 return std::unique_ptr<rvsdg::SimpleOperation>(
new OP(std::move(st), std::move(dt)));
2112static const Variable *
2115 JLM_ASSERT(::llvm::dyn_cast<::llvm::CastInst>(i));
2117 auto st = i->getOperand(0)->getType();
2118 auto dt = i->getType();
2122 bool isLaneWiseCast =
false;
2123 if (i->getOpcode() != ::llvm::Instruction::BitCast)
2125 isLaneWiseCast = st->isVectorTy();
2126 JLM_ASSERT(st->isVectorTy() == dt->isVectorTy());
2129 static std::unordered_map<
2131 std::unique_ptr<rvsdg::SimpleOperation> (*)(
2132 std::shared_ptr<const rvsdg::Type>,
2133 std::shared_ptr<const rvsdg::Type>)>
2134 map({ { ::llvm::Instruction::Trunc, create_unop<TruncOperation> },
2135 { ::llvm::Instruction::ZExt, create_unop<ZExtOperation> },
2136 { ::llvm::Instruction::UIToFP, create_unop<UIToFPOperation> },
2137 { ::llvm::Instruction::SIToFP, create_unop<SIToFPOperation> },
2138 { ::llvm::Instruction::SExt, create_unop<SExtOperation> },
2139 { ::llvm::Instruction::PtrToInt, create_unop<PtrToIntOperation> },
2140 { ::llvm::Instruction::IntToPtr, create_unop<IntToPtrOperation> },
2141 { ::llvm::Instruction::FPTrunc, create_unop<FPTruncOperation> },
2142 { ::llvm::Instruction::FPToSI, create_unop<FPToSIOperation> },
2143 { ::llvm::Instruction::FPToUI, create_unop<FPToUIOperation> },
2144 { ::llvm::Instruction::FPExt, create_unop<FPExtOperation> },
2145 { ::llvm::Instruction::BitCast, create_unop<BitCastOperation> } });
2150 auto srctype = typeConverter.ConvertLlvmType(*(isLaneWiseCast ? st->getScalarType() : st));
2151 auto dsttype = typeConverter.ConvertLlvmType(*(isLaneWiseCast ? dt->getScalarType() : dt));
2153 JLM_ASSERT(map.find(i->getOpcode()) != map.end());
2154 auto unop = map[i->getOpcode()](std::move(srctype), std::move(dsttype));
2155 JLM_ASSERT(is<rvsdg::UnaryOperation>(*unop));
2163 return tacs.back()->result(0);
2166template<
class INSTRUCTIONTYPE>
2167static const Variable *
2170 JLM_ASSERT(::llvm::isa<INSTRUCTIONTYPE>(instruction));
2171 return convert(::llvm::cast<INSTRUCTIONTYPE>(instruction), tacs, ctx);
2174static const Variable *
2176 ::llvm::Instruction * instruction,
2177 std::vector<std::unique_ptr<ThreeAddressCode>> & threeAddressCodes,
2180 switch (instruction->getOpcode())
2182 case ::llvm::Instruction::Trunc:
2183 case ::llvm::Instruction::ZExt:
2184 case ::llvm::Instruction::UIToFP:
2185 case ::llvm::Instruction::SIToFP:
2186 case ::llvm::Instruction::SExt:
2187 case ::llvm::Instruction::PtrToInt:
2188 case ::llvm::Instruction::IntToPtr:
2189 case ::llvm::Instruction::FPTrunc:
2190 case ::llvm::Instruction::FPToSI:
2191 case ::llvm::Instruction::FPToUI:
2192 case ::llvm::Instruction::FPExt:
2193 case ::llvm::Instruction::BitCast:
2195 case ::llvm::Instruction::Add:
2196 case ::llvm::Instruction::And:
2197 case ::llvm::Instruction::AShr:
2198 case ::llvm::Instruction::Sub:
2199 case ::llvm::Instruction::UDiv:
2200 case ::llvm::Instruction::SDiv:
2201 case ::llvm::Instruction::URem:
2202 case ::llvm::Instruction::SRem:
2203 case ::llvm::Instruction::Shl:
2204 case ::llvm::Instruction::LShr:
2205 case ::llvm::Instruction::Or:
2206 case ::llvm::Instruction::Xor:
2207 case ::llvm::Instruction::Mul:
2208 case ::llvm::Instruction::FAdd:
2209 case ::llvm::Instruction::FSub:
2210 case ::llvm::Instruction::FMul:
2211 case ::llvm::Instruction::FDiv:
2212 case ::llvm::Instruction::FRem:
2213 return convert<::llvm::BinaryOperator>(instruction, threeAddressCodes, context);
2214 case ::llvm::Instruction::Ret:
2216 case ::llvm::Instruction::Br:
2218 case ::llvm::Instruction::Switch:
2220 ::llvm::cast<::llvm::SwitchInst>(instruction),
2223 case ::llvm::Instruction::Unreachable:
2225 case ::llvm::Instruction::FNeg:
2226 return convert<::llvm::UnaryOperator>(instruction, threeAddressCodes, context);
2227 case ::llvm::Instruction::ICmp:
2228 return convert<::llvm::ICmpInst>(instruction, threeAddressCodes, context);
2229 case ::llvm::Instruction::FCmp:
2231 case ::llvm::Instruction::Load:
2233 case ::llvm::Instruction::Store:
2235 case ::llvm::Instruction::PHI:
2237 case ::llvm::Instruction::GetElementPtr:
2239 case ::llvm::Instruction::Call:
2241 *::llvm::dyn_cast<::llvm::CallInst>(instruction),
2244 case ::llvm::Instruction::Select:
2246 case ::llvm::Instruction::Alloca:
2248 case ::llvm::Instruction::ExtractValue:
2250 case ::llvm::Instruction::InsertValue:
2252 *::llvm::dyn_cast<::llvm::InsertValueInst>(instruction),
2255 case ::llvm::Instruction::ExtractElement:
2257 case ::llvm::Instruction::ShuffleVector:
2258 return convert<::llvm::ShuffleVectorInst>(instruction, threeAddressCodes, context);
2259 case ::llvm::Instruction::InsertElement:
2261 case ::llvm::Instruction::Freeze:
2264 throw std::runtime_error(
util::strfmt(instruction->getOpcodeName(),
" is not supported."));
2268static std::vector<::llvm::PHINode *>
2271 std::vector<::llvm::PHINode *> phis;
2272 ::llvm::ReversePostOrderTraversal<::llvm::Function *> rpotraverser(&function);
2273 for (
auto & bb : rpotraverser)
2275 for (
auto & instruction : *bb)
2285 if (!tacs.empty() && is<SsaPhiOperation>(tacs.back()->operation()))
2287 auto phi = ::llvm::dyn_cast<::llvm::PHINode>(&instruction);
2288 phis.push_back(phi);
2306 for (
const auto & phi : phis)
2308 std::vector<ControlFlowGraphNode *> incomingNodes;
2309 std::vector<const Variable *> operands;
2310 for (
size_t n = 0; n < phi->getNumOperands(); n++)
2315 if (!ctx.
has(phi->getIncomingBlock(n)))
2321 auto predecessor = ctx.
get(phi->getIncomingBlock(n));
2322 if (std::find(incomingNodes.begin(), incomingNodes.end(), predecessor) != incomingNodes.end())
2327 operands.push_back(
ConvertValue(phi->getIncomingValue(n), tacs, ctx));
2329 incomingNodes.push_back(predecessor);
2334 auto phi_tac = util::assertedCast<const ThreeAddressCodeVariable>(ctx.
lookup_value(phi))->tac();
2336 SsaPhiOperation(std::move(incomingNodes), phi_tac->result(0)->Type()),
2345 ::llvm::ReversePostOrderTraversal<::llvm::Function *> rpotraverser(&f);
2346 for (
auto & bb : rpotraverser)
2352static std::unique_ptr<llvm::Argument>
2355 auto function = argument.getParent();
2356 auto name = argument.getName().str();
2359 function->getAttributes().getParamAttrs(argument.getArgNo()),
2368 auto exitNode = cfg.
exit();
2370 if (exitNode->NumInEdges() == 0)
2392 auto stronglyConnectedComponents =
find_sccs(cfg);
2393 for (
auto stronglyConnectedComponent : stronglyConnectedComponents)
2397 if (sccStructure->NumExitEdges() == 0)
2399 auto repetitionEdge = *sccStructure->RepetitionEdges().begin();
2403 auto op = std::make_unique<rvsdg::ControlConstantOperation>(
2409 basicBlock->add_outedge(exitNode);
2410 basicBlock->add_outedge(repetitionEdge->sink());
2412 repetitionEdge->divert(basicBlock);
2418 if (exitNode->NumInEdges() == 1)
2426 exitNode->divert_inedges(basicBlock);
2427 basicBlock->add_outedge(exitNode);
2430static std::unique_ptr<ControlFlowGraph>
2440 for (
const auto & arg : f.args())
2449 JLM_ASSERT(n < node->fcttype().NumArguments());
2450 auto & type = node->fcttype().Arguments()[n++];
2453 JLM_ASSERT(n < node->fcttype().NumArguments());
2455 auto & iotype = node->fcttype().Arguments()[n++];
2456 auto iostate = cfg.entry()->append_argument(
Argument::create(
"_io_", iotype));
2458 auto & memtype = node->fcttype().Arguments()[n++];
2459 auto memstate = cfg.entry()->append_argument(
Argument::create(
"_s_", memtype));
2461 JLM_ASSERT(n == node->fcttype().NumArguments());
2468 add_arguments(f, *cfg, ctx);
2473 cfg->exit()->divert_inedges(entry_block);
2474 entry_block->add_outedge(bbmap.LookupKey(&f.getEntryBlock()));
2478 if (!f.getReturnType()->isVoidTy())
2482 result = entry_block->last()->result(0);
2484 JLM_ASSERT(node->fcttype().NumResults() == 3);
2486 cfg->exit()->append_result(result);
2488 cfg->exit()->append_result(ctx.
iostate());
2509 if (function.isDeclaration())
2515 fv->function()->add_cfg(
create_cfg(function, ctx));
2522 static std::unordered_map<::llvm::GlobalValue::LinkageTypes, llvm::Linkage> map(
2524 { ::llvm::GlobalValue::AvailableExternallyLinkage,
2537 return map[linkage];
2543 auto create_data_node = [](const ::llvm::GlobalVariable & gv,
Context & ctx)
2545 auto name = gv.getName().str();
2546 auto constant = gv.isConstant();
2549 auto section = gv.getSection().str();
2550 const auto alignment = gv.getAlign().valueOrOne().value();
2562 auto create_function_node = [](const ::llvm::Function & f,
Context & ctx)
2564 auto name = f.getName().str();
2579 for (
auto & gv : lm.globals())
2581 auto node = create_data_node(gv, ctx);
2585 for (
auto & f : lm.getFunctionList())
2590 auto node = create_function_node(f, ctx);
2595static std::unique_ptr<DataNodeInit>
2598 if (!gv.hasInitializer())
2601 auto init = gv.getInitializer();
2604 return std::make_unique<DataNodeInit>(ctx.
lookup_value(init));
2606 return std::make_unique<DataNodeInit>(std::move(tacs));
2622 for (
auto & gv : lm.globals())
2625 for (
auto & f : lm.getFunctionList())
2629std::unique_ptr<InterProceduralGraphModule>
2634 llvmModule.getTargetTriple(),
2635 llvmModule.getDataLayoutStr());
util::HashSet< rvsdg::Output * > arguments
static std::unique_ptr< ThreeAddressCode > createTac(const Variable &operand1, const Variable &operand2)
static std::unique_ptr< ThreeAddressCode > createTac(std::shared_ptr< const rvsdg::Type > allocatedType, const Variable *count, size_t alignment)
static std::unique_ptr< Argument > create(const std::string &name, std::shared_ptr< const jlm::rvsdg::Type > type, const AttributeSet &attributes)
static std::unique_ptr< llvm::ThreeAddressCode > create(const Variable *rhs, const Variable *lhs)
void InsertTypeAttribute(const TypeAttribute &attribute)
void InsertStringAttribute(const StringAttribute &attribute)
void InsertEnumAttribute(const EnumAttribute &attribute)
void InsertIntAttribute(const IntAttribute &attribute)
@ None
No attributes have been set.
@ EndAttrKinds
Sentinel value useful for loops.
@ SpeculativeLoadHardening
@ CoroDestroyOnlyWhenComplete
@ DisableSanitizerInstrumentation
static std::unique_ptr< ThreeAddressCode > createTac(const Variable &operand)
llvm::ThreeAddressCode * append_last(std::unique_ptr< llvm::ThreeAddressCode > tac)
llvm::ThreeAddressCode * insert_before_branch(std::unique_ptr< llvm::ThreeAddressCode > tac)
static BasicBlock * create(ControlFlowGraph &cfg)
static std::unique_ptr< llvm::ThreeAddressCode > create(size_t nalternatives, const Variable *operand)
static std::unique_ptr< ThreeAddressCode > create(const Variable *function, std::shared_ptr< const rvsdg::FunctionType > functionType, CallingConvention callingConvention, AttributeList attributes, const std::vector< const Variable * > &arguments)
static std::unique_ptr< ThreeAddressCode > createTac(const Variable &operand)
static std::unique_ptr< llvm::ThreeAddressCode > create(std::shared_ptr< const jlm::rvsdg::Type > type)
static std::unique_ptr< llvm::ThreeAddressCode > create(const std::vector< const Variable * > &elements)
static std::unique_ptr< ThreeAddressCode > create(const std::vector< const Variable * > &elements)
static std::unique_ptr< ThreeAddressCode > Create(const std::vector< const Variable * > &elements)
static std::unique_ptr< llvm::ThreeAddressCode > createTac(const ::llvm::APFloat &constant, const std::shared_ptr< const jlm::rvsdg::Type > &type)
static std::unique_ptr< ThreeAddressCode > createTac()
static std::unique_ptr< ThreeAddressCode > create(const std::vector< const Variable * > &elements, const std::shared_ptr< const rvsdg::Type > &type)
static std::unique_ptr< llvm::ThreeAddressCode > create(const std::vector< const Variable * > &operands, const std::shared_ptr< const jlm::rvsdg::Type > &type)
const llvm::Variable * result() const noexcept
TypeConverter & GetTypeConverter() noexcept
Context(InterProceduralGraphModule &im)
bool has_value(const ::llvm::Value *value) const noexcept
InterProceduralGraphNode * node() const noexcept
InterProceduralGraphModule & module() const noexcept
const llvm::Variable * result_
void set_memory_state(llvm::Variable *state)
void set_iostate(llvm::Variable *state)
llvm::Variable * iostate() const noexcept
void set_result(const llvm::Variable *result)
TypeConverter TypeConverter_
void set_basic_block_map(BasicBlockMap bbmap)
BasicBlock * get(const ::llvm::BasicBlock *bb) const noexcept
void set_node(InterProceduralGraphNode *node) noexcept
llvm::Variable * memory_state_
bool has(BasicBlock *bb) const noexcept
const ::llvm::BasicBlock * get(BasicBlock *bb) const noexcept
std::unordered_map< const ::llvm::Value *, const llvm::Variable * > vmap_
llvm::Variable * iostate_
llvm::Variable * memory_state() const noexcept
void insert_value(const ::llvm::Value *value, const llvm::Variable *variable)
bool has(const ::llvm::BasicBlock *bb) const noexcept
InterProceduralGraphNode * node_
const llvm::Variable * lookup_value(const ::llvm::Value *value) const noexcept
InterProceduralGraphModule & module_
size_t index() const noexcept
ControlFlowGraphEdge * add_outedge(ControlFlowGraphNode *sink)
ExitNode * exit() const noexcept
static std::unique_ptr< ControlFlowGraph > create(InterProceduralGraphModule &im)
static std::unique_ptr< ThreeAddressCode > createTac(const Variable &operand1, const Variable &operand2)
static std::unique_ptr< ThreeAddressCode > createTac(const Variable &operand, const Variable &isZeroPoison)
static std::unique_ptr< ThreeAddressCode > createTac(const Variable &operand)
static std::unique_ptr< ThreeAddressCode > createTac(const Variable &operand, const Variable &isZeroPoison)
static DataNode * Create(InterProceduralGraph &clg, const std::string &name, std::shared_ptr< const jlm::rvsdg::Type > valueType, const llvm::Linkage &linkage, std::string section, const bool constant, const size_t alignment)
static std::unique_ptr< ThreeAddressCode > createTac(const Variable &operand)
static std::unique_ptr< ThreeAddressCode > CreateTac(const Variable &multiplier, const Variable &multiplicand, const Variable &summand)
static std::unique_ptr< llvm::ThreeAddressCode > create(const Variable *operand)
static std::unique_ptr< ThreeAddressCode > createTac(const Variable &operand1, const Variable &operand2, const Variable &operand3)
static std::unique_ptr< ThreeAddressCode > createTac(const Variable &operand)
static std::unique_ptr< llvm::ThreeAddressCode > Create(const Variable *pointer, const std::vector< const Variable * > &memoryStates, const Variable *iOState)
static std::unique_ptr< llvm::ThreeAddressCode > createTac(const Variable &operand)
static FunctionNode * create(InterProceduralGraph &ipg, const std::string &name, std::shared_ptr< const rvsdg::FunctionType > type, const llvm::Linkage &linkage, const CallingConvention &callingConvention, const AttributeSet &attributes)
static std::unique_ptr< ThreeAddressCode > createTAC(const Variable *baseAddress, const std::vector< const Variable * > &offsets, std::shared_ptr< const rvsdg::Type > gepType)
static std::unique_ptr< llvm::ThreeAddressCode > create(const llvm::Variable *vector, const llvm::Variable *value, const llvm::Variable *index)
static std::unique_ptr< ThreeAddressCode > createTac(const Variable &aggregateOperand, const Variable &valueOperand, std::vector< unsigned > indices)
static std::unique_ptr< InterProceduralGraphModule > create(const jlm::util::FilePath &sourceFilename, const std::string &targetTriple, const std::string &dataLayout)
llvm::Variable * create_variable(std::shared_ptr< const jlm::rvsdg::Type > type, const std::string &name)
InterProceduralGraph & ipgraph() noexcept
GlobalValue * create_global_value(DataNode *node)
void add_dependency(const InterProceduralGraphNode *dep)
static std::unique_ptr< ThreeAddressCode > createTac(const Variable &operand)
static std::unique_ptr< ThreeAddressCode > createTac(const Variable &operand1, const Variable &operand2)
static std::unique_ptr< llvm::ThreeAddressCode > Create(const Variable *address, const Variable *state, std::shared_ptr< const rvsdg::Type > loadedType, size_t alignment)
static std::unique_ptr< llvm::ThreeAddressCode > Create(const Variable *address, const Variable *iOState, const Variable *memoryState, std::shared_ptr< const rvsdg::Type > loadedType, size_t alignment)
static std::unique_ptr< ThreeAddressCode > createTac(const Variable *size, const Variable *ioState)
static std::unique_ptr< llvm::ThreeAddressCode > create(const Variable *destination, const Variable *source, const Variable *length, const std::vector< const Variable * > &memoryStates)
static std::unique_ptr< llvm::ThreeAddressCode > CreateThreeAddressCode(const Variable &destination, const Variable &source, const Variable &length, const Variable &ioState, const std::vector< const Variable * > &memoryStates)
static std::unique_ptr< ThreeAddressCode > createTac(const Variable &dest, const Variable &src, const Variable &length, const std::vector< const Variable * > &memoryStates)
static std::unique_ptr< ThreeAddressCode > createTac(const Variable &destination, const Variable &value, const Variable &length, const std::vector< const Variable * > &memoryStates)
static rvsdg::Output * Create(const std::vector< rvsdg::Output * > &operands)
static std::shared_ptr< const PointerType > Create()
static std::unique_ptr< llvm::ThreeAddressCode > Create(const std::shared_ptr< const jlm::rvsdg::Type > &type)
static std::unique_ptr< ThreeAddressCode > createTac(const Variable &ptrOperand, const Variable &maskOperand)
static std::unique_ptr< ThreeAddressCode > createTac(const Variable &operand)
static std::unique_ptr< ThreeAddressCode > createTac(const Variable &operand)
static std::unique_ptr< ThreeAddressCode > createTac(const Variable &operand1, const Variable &operand2)
static std::unique_ptr< ThreeAddressCode > createTac(const Variable &operand1, const Variable &operand2)
static std::unique_ptr< ThreeAddressCode > createTac(const Variable &operand1, const Variable &operand2)
static std::unique_ptr< ThreeAddressCode > createTac(const Variable &operand1, const Variable &operand2)
static std::unique_ptr< ThreeAddressCode > createTac(const Variable &operand1, const Variable &operand2)
static std::unique_ptr< llvm::ThreeAddressCode > create(const llvm::Variable *p, const llvm::Variable *t, const llvm::Variable *f)
static std::unique_ptr< llvm::ThreeAddressCode > create(const Variable *v1, const Variable *v2, const std::vector< int > &mask)
static std::unique_ptr< llvm::ThreeAddressCode > create(const std::vector< std::pair< const Variable *, ControlFlowGraphNode * > > &arguments, std::shared_ptr< const jlm::rvsdg::Type > type)
static std::unique_ptr< llvm::ThreeAddressCode > Create(const Variable *address, const Variable *value, const Variable *state, size_t alignment)
static std::unique_ptr< llvm::ThreeAddressCode > Create(const Variable *address, const Variable *value, const Variable *ioState, const Variable *memoryState, size_t alignment)
static std::unique_ptr< StronglyConnectedComponentStructure > Create(const StronglyConnectedComponent &scc)
static std::unique_ptr< llvm::ThreeAddressCode > create(std::unique_ptr< rvsdg::SimpleOperation > operation, const std::vector< const Variable * > &operands)
static std::unique_ptr< ThreeAddressCode > createTac(const Variable &operand)
::llvm::PointerType * ConvertPointerType(const PointerType &type, ::llvm::LLVMContext &context)
::llvm::FunctionType * ConvertFunctionType(const rvsdg::FunctionType &functionType, ::llvm::LLVMContext &context)
std::shared_ptr< const rvsdg::Type > ConvertLlvmType(::llvm::Type &type)
static std::unique_ptr< ThreeAddressCode > createTac(const Variable &operand1, const Variable &operand2)
static std::unique_ptr< ThreeAddressCode > createTac(const Variable &operand1, const Variable &operand2)
static std::unique_ptr< ThreeAddressCode > createTac(const Variable &operand1, const Variable &operand2)
static std::unique_ptr< ThreeAddressCode > createTac(const Variable &operand1, const Variable &operand2)
static jlm::rvsdg::Output * Create(rvsdg::Region ®ion, std::shared_ptr< const jlm::rvsdg::Type > type)
const jlm::rvsdg::Type & type() const noexcept
const std::shared_ptr< const jlm::rvsdg::Type > Type() const noexcept
static std::unique_ptr< llvm::ThreeAddressCode > create(const std::vector< const Variable * > &arguments)
static std::unique_ptr< llvm::ThreeAddressCode > create(const rvsdg::BinaryOperation &binop, const llvm::Variable *op1, const llvm::Variable *op2, const std::shared_ptr< const jlm::rvsdg::Type > &type)
static std::unique_ptr< llvm::ThreeAddressCode > create(const Variable *p, const Variable *t, const Variable *f)
static std::unique_ptr< llvm::ThreeAddressCode > create(const rvsdg::UnaryOperation &unop, const llvm::Variable *operand, const std::shared_ptr< const jlm::rvsdg::Type > &type)
BitValueRepresentation sext(size_t nbits) const
BitValueRepresentation zext(size_t nbits) const
const V & LookupKey(const K &key) const
const K & LookupValue(const V &value) const
bool Insert(const K &key, const V &value)
bool HasKey(const K &key) const noexcept
bool HasValue(const V &value) const noexcept
#define JLM_UNREACHABLE(msg)
Global memory state passed between functions.
static const Variable * convertPtrMaskIntrinsic(const ::llvm::CallInst &instruction, tacsvector_t &tacs, Context &context)
static const Variable * convertInstruction(::llvm::Instruction *instruction, std::vector< std::unique_ptr< ThreeAddressCode > > &threeAddressCodes, Context &context)
std::vector< const Variable * > convertCallArguments(const ::llvm::CallInst &callInstruction, tacsvector_t &threeAddressCodes, Context &context)
static const Variable * convertFShlIntrinsic(const ::llvm::CallInst &instruction, tacsvector_t &tacs, Context &context)
static const Variable * convertFreezeInstruction(::llvm::Instruction *i, tacsvector_t &tacs, Context &ctx)
static rvsdg::BitValueRepresentation convert_apint(const ::llvm::APInt &value)
static const Variable * convertSAddWithOverflowIntrinsic(const ::llvm::CallInst &instruction, tacsvector_t &tacs, Context &context)
static void convert_globals(::llvm::Module &lm, Context &ctx)
static const Variable * convert_insertelement_instruction(::llvm::Instruction *i, tacsvector_t &tacs, Context &ctx)
static const Variable * convert_unreachable_instruction(::llvm::Instruction *i, tacsvector_t &, Context &ctx)
ICmpPredicate convertICmpPredicateToJlm(::llvm::CmpInst::Predicate predicate)
static const Variable * convertFMulAddIntrinsic(const ::llvm::CallInst &instruction, tacsvector_t &tacs, Context &ctx)
static const Variable * convertInsertValueInstruction(const ::llvm::InsertValueInst &instruction, tacsvector_t &tacs, Context &context)
static const Variable * convert_constantVector(::llvm::Constant *c, std::vector< std::unique_ptr< llvm::ThreeAddressCode > > &tacs, Context &ctx)
static const Variable * convertSSubWithOverflowIntrinsic(const ::llvm::CallInst &instruction, tacsvector_t &tacs, Context &context)
std::vector< StronglyConnectedComponent > find_sccs(const ControlFlowGraph &cfg)
static const Variable * convert_globalAlias(::llvm::Constant *constant, std::vector< std::unique_ptr< llvm::ThreeAddressCode > > &, Context &)
static std::unique_ptr< rvsdg::BinaryOperation > ConvertPointerIcmpPredicate(const ::llvm::CmpInst::Predicate predicate)
static const Variable * createCall(const ::llvm::CallInst &callInstruction, tacsvector_t &threeAddressCodes, Context &context)
static ControlFlowGraphNode * aggregate(ControlFlowGraphNode *, ControlFlowGraphNode *, AggregationMap &)
static const Variable * convertCeilIntrinsic(const ::llvm::CallInst &instruction, tacsvector_t &tacs, Context &context)
static bool shouldIgnoreIntrinsic(::llvm::Intrinsic::ID intrinsicId)
static IntAttribute ConvertIntAttribute(const ::llvm::Attribute &attribute)
static const Variable * convertRoundIntrinsic(const ::llvm::CallInst &instruction, tacsvector_t &tacs, Context &context)
static const Variable * convertRIntIntrinsic(const ::llvm::CallInst &instruction, tacsvector_t &tacs, Context &context)
std::vector< std::unique_ptr< llvm::ThreeAddressCode > > tacsvector_t
static const Variable * convertBSwapIntrinsic(const ::llvm::CallInst &instruction, tacsvector_t &tacs, Context &context)
static BasicBlockMap convert_basic_blocks(::llvm::Function &f, ControlFlowGraph &cfg)
static const Variable * convert_alloca_instruction(::llvm::Instruction *instruction, tacsvector_t &tacs, Context &ctx)
static TypeAttribute ConvertTypeAttribute(const ::llvm::Attribute &attribute, TypeConverter &typeConverter)
static std::unique_ptr< ControlFlowGraph > create_cfg(::llvm::Function &f, Context &ctx)
static EnumAttribute ConvertEnumAttribute(const ::llvm::Attribute &attribute)
static const Variable * convert_constantPointerNull(::llvm::Constant *constant, std::vector< std::unique_ptr< llvm::ThreeAddressCode > > &tacs, Context &ctx)
static const Variable * convertMallocCall(const ::llvm::CallInst &instruction, tacsvector_t &threeAddressCodes, Context &context)
static const Variable * convertUAddWithOverflowIntrinsic(const ::llvm::CallInst &instruction, tacsvector_t &tacs, Context &context)
const Variable * ConvertValueOrFunction(::llvm::Value *v, tacsvector_t &tacs, Context &ctx)
std::unique_ptr< InterProceduralGraphModule > ConvertLlvmModule(::llvm::Module &llvmModule)
static const Variable * convert_extractelement_instruction(::llvm::Instruction *i, tacsvector_t &tacs, Context &ctx)
static bool isMallocCall(const ::llvm::CallInst &callInstruction)
static std::unique_ptr< rvsdg::BinaryOperation > ConvertIntegerBinaryOperation(const ::llvm::Instruction::BinaryOps binaryOperation, std::size_t numBits)
jlm::llvm::CallingConvention convertCallingConventionToJlm(::llvm::CallingConv::ID cc)
static const Variable * convertSwitchInstruction(::llvm::SwitchInst *switchInstruction, tacsvector_t &tacs, Context &ctx)
static const Variable * convert_return_instruction(::llvm::Instruction *instruction, tacsvector_t &tacs, Context &ctx)
static const Variable * convert_undefvalue(::llvm::Constant *c, std::vector< std::unique_ptr< llvm::ThreeAddressCode > > &tacs, Context &ctx)
static const Variable * convert_cast_instruction(::llvm::Instruction *i, tacsvector_t &tacs, Context &ctx)
@ availableExternallyLinkage
static void PatchPhiOperands(const std::vector<::llvm::PHINode * > &phis, Context &ctx)
static const Variable * convert_constantArray(::llvm::Constant *c, std::vector< std::unique_ptr< llvm::ThreeAddressCode > > &tacs, Context &ctx)
static const Variable * convert_getelementptr_instruction(::llvm::Instruction *inst, tacsvector_t &tacs, Context &ctx)
static const Variable * convert_extractvalue(::llvm::Instruction *i, tacsvector_t &tacs, Context &ctx)
static const Variable * convert_constantExpr(::llvm::Constant *constant, std::vector< std::unique_ptr< llvm::ThreeAddressCode > > &tacs, Context &ctx)
static const Variable * convert_constantDataVector(::llvm::Constant *constant, std::vector< std::unique_ptr< llvm::ThreeAddressCode > > &tacs, Context &ctx)
static const Variable * ConvertConstantStruct(::llvm::Constant *c, std::vector< std::unique_ptr< llvm::ThreeAddressCode > > &tacs, Context &ctx)
static const Variable * ConvertConstant(::llvm::Constant *, std::vector< std::unique_ptr< llvm::ThreeAddressCode > > &, Context &)
static const Variable * convertSMinIntrinsic(const ::llvm::CallInst &instruction, tacsvector_t &tacs, Context &context)
static const Variable * convert_blockAddress(::llvm::Constant *constant, std::vector< std::unique_ptr< llvm::ThreeAddressCode > > &, Context &)
static const Variable * convert_constantAggregateZero(::llvm::Constant *c, std::vector< std::unique_ptr< llvm::ThreeAddressCode > > &tacs, Context &ctx)
static AttributeSet convert_attributes(const ::llvm::AttributeSet &as, TypeConverter &typeConverter)
static std::unique_ptr< rvsdg::SimpleOperation > create_unop(std::shared_ptr< const rvsdg::Type > st, std::shared_ptr< const rvsdg::Type > dt)
const Variable * ConvertValue(::llvm::Value *v, tacsvector_t &tacs, Context &ctx)
static const Variable * ConvertPhiInstruction(::llvm::Instruction *i, tacsvector_t &tacs, Context &ctx)
static const Variable * convertUMaxIntrinsic(const ::llvm::CallInst &instruction, tacsvector_t &tacs, Context &context)
static const Variable * convertFloorIntrinsic(const ::llvm::CallInst &instruction, tacsvector_t &tacs, Context &context)
static const Variable * convertSMaxIntrinsic(const ::llvm::CallInst &instruction, tacsvector_t &tacs, Context &context)
static const Variable * convertSMulWithOverflowIntrinsic(const ::llvm::CallInst &instruction, tacsvector_t &tacs, Context &context)
static const Variable * convertCtlzIntrinsic(const ::llvm::CallInst &instruction, tacsvector_t &tacs, Context &context)
static const Variable * convert(const ::llvm::ICmpInst *instruction, tacsvector_t &tacs, Context &ctx)
static const Variable * convertCallInstruction(const ::llvm::CallInst &callInstruction, tacsvector_t &threeAddressCodes, Context &context)
static const Variable * convertMemCpyCall(const ::llvm::IntrinsicInst *instruction, tacsvector_t &threeAddressCodes, Context &context)
static std::vector<::llvm::PHINode * > convert_instructions(::llvm::Function &function, Context &ctx)
static const Variable * convertIntrinsicInstruction(const ::llvm::IntrinsicInst &intrinsicInstruction, tacsvector_t &threeAddressCodes, Context &context)
static const Variable * convert_constantDataArray(::llvm::Constant *constant, std::vector< std::unique_ptr< llvm::ThreeAddressCode > > &tacs, Context &ctx)
static void declare_globals(::llvm::Module &lm, Context &ctx)
static StringAttribute ConvertStringAttribute(const ::llvm::Attribute &attribute)
static const Variable * convert_fcmp_instruction(::llvm::Instruction *instruction, tacsvector_t &tacs, Context &ctx)
static std::unique_ptr< rvsdg::BinaryOperation > ConvertIntegerIcmpPredicate(const ::llvm::CmpInst::Predicate predicate, const std::size_t numBits)
static void convert_global_value(::llvm::GlobalVariable &gv, Context &ctx)
static const Variable * convertUMinIntrinsic(const ::llvm::CallInst &instruction, tacsvector_t &tacs, Context &context)
static const Variable * convertCopysignIntrinsic(const ::llvm::CallInst &instruction, tacsvector_t &tacs, Context &context)
static const Variable * convertMemSetCall(const ::llvm::IntrinsicInst &instruction, tacsvector_t &threeAddressCodes, Context &context)
static const Variable * convertTruncIntrinsic(const ::llvm::CallInst &instruction, tacsvector_t &tacs, Context &context)
void straighten(ControlFlowGraph &cfg)
static const Variable * convertIsConstantIntrinsic(const ::llvm::CallInst &instruction, tacsvector_t &tacs, Context &context)
static const Variable * convert_globalVariable(::llvm::Constant *c, std::vector< std::unique_ptr< llvm::ThreeAddressCode > > &tacs, Context &ctx)
static std::unique_ptr< rvsdg::BinaryOperation > ConvertFloatingPointBinaryOperation(const ::llvm::Instruction::BinaryOps binaryOperation, fpsize floatingPointSize)
static const Variable * AddIOBarrier(tacsvector_t &tacs, const Variable *operand, const Context &ctx)
static const Variable * convertIsFPClassIntrinsic(const ::llvm::CallInst &instruction, tacsvector_t &tacs, Context &context)
static bool IsVolatile(const ::llvm::Value &value)
static const Variable * convertFreeCall(const ::llvm::CallInst &instruction, tacsvector_t &threeAddressCodes, Context &context)
static const Variable * ConvertBranchInstruction(::llvm::Instruction *instruction, tacsvector_t &tacs, Context &ctx)
static const Variable * convertFAbsIntrinsic(const ::llvm::CallInst &instruction, tacsvector_t &tacs, Context &context)
static bool isFreeCall(const ::llvm::CallInst &callInstruction)
static const Variable * convertUMulWithOverflowIntrinsic(const ::llvm::CallInst &instruction, tacsvector_t &tacs, Context &context)
static void EnsureSingleInEdgeToExitNode(ControlFlowGraph &cfg)
static std::unique_ptr< llvm::Argument > convert_argument(const ::llvm::Argument &argument, Context &ctx)
Attribute::kind ConvertAttributeKind(const ::llvm::Attribute::AttrKind &kind)
static const Variable * convertCtpopIntrinsic(const ::llvm::CallInst &instruction, tacsvector_t &tacs, Context &context)
static std::unique_ptr< DataNodeInit > create_initialization(::llvm::GlobalVariable &gv, Context &ctx)
static const Variable * convert_function(::llvm::Constant *c, tacsvector_t &tacs, Context &ctx)
util::BijectiveMap< const ::llvm::BasicBlock *, BasicBlock * > BasicBlockMap
static const Variable * convertMemMoveCall(const ::llvm::IntrinsicInst &instruction, tacsvector_t &threeAddressCodes, Context &context)
static const llvm::Linkage & convert_linkage(const ::llvm::GlobalValue::LinkageTypes &linkage)
static const Variable * convert_store_instruction(::llvm::Instruction *i, tacsvector_t &tacs, Context &ctx)
static const Variable * convertCttzIntrinsic(const ::llvm::CallInst &instruction, tacsvector_t &tacs, Context &context)
AttributeList convertAttributeList(const ::llvm::AttributeList &attributeList, const size_t numParameters, TypeConverter &typeConverter)
static const Variable * convert_int_constant(::llvm::Constant *c, std::vector< std::unique_ptr< ThreeAddressCode > > &tacs, Context &)
static const Variable * convert_select_instruction(::llvm::Instruction *i, tacsvector_t &tacs, Context &ctx)
static const Variable * convertAbsIntrinsic(const ::llvm::CallInst &instruction, tacsvector_t &tacs, Context &context)
static const Variable * convert_load_instruction(::llvm::Instruction *i, tacsvector_t &tacs, Context &ctx)
static const Variable * convert_constantFP(::llvm::Constant *constant, std::vector< std::unique_ptr< llvm::ThreeAddressCode > > &tacs, Context &ctx)
void prune(ControlFlowGraph &cfg)
static std::string strfmt(Args... args)