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 const Variable *
986 auto hoistBarrierOperation = std::make_unique<MemoryHoistBarrierOperation>(0);
989 return tacs.back()->result(0);
992static inline const Variable *
995 JLM_ASSERT(i->getOpcode() == ::llvm::Instruction::Load);
996 auto instruction =
static_cast<::llvm::LoadInst *
>(i);
998 auto alignment = instruction->getAlign().value();
999 auto address =
ConvertValue(instruction->getPointerOperand(), tacs, ctx);
1008 if (instruction->isVolatile())
1016 tacs.push_back(std::move(loadVolatileTac));
1018 loadedValue = tacs.back()->result(0);
1019 ioState = tacs.back()->result(1);
1020 memoryState = tacs.back()->result(2);
1027 tacs.push_back(std::move(loadTac));
1028 loadedValue = tacs.back()->result(0);
1029 memoryState = tacs.back()->result(1);
1041static inline const Variable *
1044 JLM_ASSERT(i->getOpcode() == ::llvm::Instruction::Store);
1045 auto instruction =
static_cast<::llvm::StoreInst *
>(i);
1047 auto alignment = instruction->getAlign().value();
1048 auto address =
ConvertValue(instruction->getPointerOperand(), tacs, ctx);
1049 auto value =
ConvertValue(instruction->getValueOperand(), tacs, ctx);
1056 if (instruction->isVolatile())
1064 tacs.push_back(std::move(storeVolatileTac));
1065 ioState = tacs.back()->result(0);
1066 memoryState = tacs.back()->result(1);
1073 tacs.push_back(std::move(storeTac));
1074 memoryState = tacs.back()->result(0);
1086static const Variable *
1095 return tacs.back()->result(0);
1098static const Variable *
1101 JLM_ASSERT(::llvm::dyn_cast<const ::llvm::GetElementPtrInst>(inst));
1103 auto i = ::llvm::cast<::llvm::GetElementPtrInst>(inst);
1105 std::vector<const Variable *> indices;
1106 auto base =
ConvertValue(i->getPointerOperand(), tacs, ctx);
1107 for (
auto it = i->idx_begin(); it != i->idx_end(); it++)
1110 auto pointeeType = typeConverter.ConvertLlvmType(*i->getSourceElementType());
1114 return tacs.back()->result(0);
1117static const Variable *
1119 const ::llvm::CallInst & instruction,
1124 const auto globalIOState = context.
iostate();
1126 const auto size =
ConvertValue(instruction.getArgOperand(0), threeAddressCodes, context);
1129 const auto mallocAddress = threeAddressCodes.back()->result(0);
1130 const auto mallocIOState = threeAddressCodes.back()->result(1);
1131 auto mallocMemoryState = threeAddressCodes.back()->result(2);
1135 threeAddressCodes.push_back(
1137 threeAddressCodes.push_back(
1140 return mallocAddress;
1143static const Variable *
1145 const ::llvm::CallInst & instruction,
1149 const auto ioState = context.
iostate();
1152 const auto pointer =
ConvertValue(instruction.getArgOperand(0), threeAddressCodes, context);
1155 const auto & freeThreeAddressCode = *threeAddressCodes.back().get();
1157 threeAddressCodes.push_back(
1175 const auto constant = ::llvm::dyn_cast<const ::llvm::ConstantInt>(&value);
1176 JLM_ASSERT(constant !=
nullptr && constant->getType()->getIntegerBitWidth() == 1);
1178 const auto apInt = constant->getValue();
1181 return apInt.isOne();
1184static const Variable *
1186 const ::llvm::IntrinsicInst * instruction,
1191 instruction->getIntrinsicID() == ::llvm::Intrinsic::memcpy
1192 || instruction->getIntrinsicID() == ::llvm::Intrinsic::memcpy_inline
1193 || instruction->getIntrinsicID() == ::llvm::Intrinsic::memcpy_element_unordered_atomic);
1195 if (instruction->getIntrinsicID() == ::llvm::Intrinsic::memcpy_inline)
1196 throw std::logic_error(
"Unhandled memcpy_inline intrinsic.");
1197 if (instruction->getIntrinsicID() == ::llvm::Intrinsic::memcpy_element_unordered_atomic)
1198 throw std::logic_error(
"Unhandled memcpy_element_unordered_atomic intrinsic.");
1200 const auto ioState = context.
iostate();
1203 const auto destination =
ConvertValue(instruction->getArgOperand(0), threeAddressCodes, context);
1204 const auto source =
ConvertValue(instruction->getArgOperand(1), threeAddressCodes, context);
1205 const auto length =
ConvertValue(instruction->getArgOperand(2), threeAddressCodes, context);
1207 if (
IsVolatile(*instruction->getArgOperand(3)))
1215 const auto & memCpyVolatileTac = *threeAddressCodes.back();
1217 threeAddressCodes.push_back(
1222 threeAddressCodes.push_back(
1224 threeAddressCodes.push_back(
1231static const Variable *
1233 const ::llvm::IntrinsicInst & instruction,
1238 instruction.getIntrinsicID() == ::llvm::Intrinsic::memset
1239 || instruction.getIntrinsicID() == ::llvm::Intrinsic::memset_inline
1240 || instruction.getIntrinsicID() == ::llvm::Intrinsic::memset_element_unordered_atomic);
1242 if (instruction.getIntrinsicID() == ::llvm::Intrinsic::memset_inline)
1243 throw std::logic_error(
"Unhandled memset_inline intrinsic.");
1244 if (instruction.getIntrinsicID() == ::llvm::Intrinsic::memset_element_unordered_atomic)
1245 throw std::logic_error(
"Unhandled memset_element_unordered_atomic intrinsic.");
1249 const auto destination =
ConvertValue(instruction.getArgOperand(0), threeAddressCodes, context);
1250 const auto value =
ConvertValue(instruction.getArgOperand(1), threeAddressCodes, context);
1251 const auto length =
ConvertValue(instruction.getArgOperand(2), threeAddressCodes, context);
1253 if (
IsVolatile(*instruction.getArgOperand(3)))
1255 throw std::logic_error(
"Unhandled volatile memset intrinsic.");
1259 threeAddressCodes.push_back(
1261 threeAddressCodes.push_back(
1268static const Variable *
1270 const ::llvm::IntrinsicInst & instruction,
1275 instruction.getIntrinsicID() == ::llvm::Intrinsic::memmove
1276 || instruction.getIntrinsicID() == ::llvm::Intrinsic::memmove_element_unordered_atomic);
1278 if (instruction.getIntrinsicID() == ::llvm::Intrinsic::memmove_element_unordered_atomic)
1279 throw std::logic_error(
"Unhandled memmove_element_unordered_atomic intrinsic.");
1283 const auto destOperand =
ConvertValue(instruction.getArgOperand(0), threeAddressCodes, context);
1284 const auto srcOperand =
ConvertValue(instruction.getArgOperand(1), threeAddressCodes, context);
1285 const auto lengthOperand =
ConvertValue(instruction.getArgOperand(2), threeAddressCodes, context);
1287 if (
IsVolatile(*instruction.getArgOperand(3)))
1289 throw std::logic_error(
"Unhandled volatile memmove intrinsic.");
1297 threeAddressCodes.push_back(
1306 const auto function = callInstruction.getCalledFunction();
1307 return function && function->getName() ==
"malloc";
1313 const auto function = callInstruction.getCalledFunction();
1314 return function && function->getName() ==
"free";
1317static const Variable *
1320 const auto multiplier =
ConvertValue(instruction.getArgOperand(0), tacs, ctx);
1321 const auto multiplicand =
ConvertValue(instruction.getArgOperand(1), tacs, ctx);
1322 const auto summand =
ConvertValue(instruction.getArgOperand(2), tacs, ctx);
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 operand =
ConvertValue(instruction.getArgOperand(0), tacs, context);
1370 return tacs.back()->result(0);
1373static const Variable *
1376 const auto operand1 =
ConvertValue(instruction.getArgOperand(0), tacs, context);
1377 const auto operand2 =
ConvertValue(instruction.getArgOperand(1), tacs, context);
1378 const auto operand3 =
ConvertValue(instruction.getArgOperand(2), tacs, context);
1381 return tacs.back()->result(0);
1384static const Variable *
1387 const auto operand1 =
ConvertValue(instruction.getArgOperand(0), tacs, context);
1388 const auto operand2 =
ConvertValue(instruction.getArgOperand(1), tacs, context);
1391 return tacs.back()->result(0);
1394static const Variable *
1397 const auto operand1 =
ConvertValue(instruction.getArgOperand(0), tacs, context);
1398 const auto operand2 =
ConvertValue(instruction.getArgOperand(1), tacs, context);
1401 return tacs.back()->result(0);
1404static const Variable *
1407 const auto operand1 =
ConvertValue(instruction.getArgOperand(0), tacs, context);
1408 const auto operand2 =
ConvertValue(instruction.getArgOperand(1), tacs, context);
1411 return tacs.back()->result(0);
1414static const Variable *
1417 const auto operand1 =
ConvertValue(instruction.getArgOperand(0), tacs, context);
1418 const auto operand2 =
ConvertValue(instruction.getArgOperand(1), tacs, context);
1421 return tacs.back()->result(0);
1424static const Variable *
1426 const ::llvm::CallInst & instruction,
1430 const auto operand1 =
ConvertValue(instruction.getArgOperand(0), tacs, context);
1431 const auto operand2 =
ConvertValue(instruction.getArgOperand(1), tacs, context);
1434 return tacs.back()->result(0);
1437static const Variable *
1439 const ::llvm::CallInst & instruction,
1443 const auto ptrOperand =
ConvertValue(instruction.getArgOperand(0), tacs, context);
1444 const auto maskOperand =
ConvertValue(instruction.getArgOperand(1), tacs, context);
1447 return tacs.back()->result(0);
1450static const Variable *
1453 const auto operand =
ConvertValue(instruction.getArgOperand(0), tacs, context);
1456 return tacs.back()->result(0);
1459static const Variable *
1462 const auto operand1 =
ConvertValue(instruction.getArgOperand(0), tacs, context);
1463 const auto operand2 =
ConvertValue(instruction.getArgOperand(1), tacs, context);
1466 return tacs.back()->result(0);
1469static const Variable *
1472 const auto operand =
ConvertValue(instruction.getArgOperand(0), tacs, context);
1475 return tacs.back()->result(0);
1478static const Variable *
1481 const auto operand1 =
ConvertValue(instruction.getArgOperand(0), tacs, context);
1482 const auto operand2 =
ConvertValue(instruction.getArgOperand(1), tacs, context);
1485 return tacs.back()->result(0);
1488static const Variable *
1491 const auto operand1 =
ConvertValue(instruction.getArgOperand(0), tacs, context);
1492 const auto operand2 =
ConvertValue(instruction.getArgOperand(1), tacs, context);
1495 return tacs.back()->result(0);
1498static const Variable *
1501 const auto operand =
ConvertValue(instruction.getArgOperand(0), tacs, context);
1504 return tacs.back()->result(0);
1507static const Variable *
1509 const ::llvm::CallInst & instruction,
1513 const auto operand =
ConvertValue(instruction.getArgOperand(0), tacs, context);
1516 return tacs.back()->result(0);
1519static const Variable *
1521 const ::llvm::CallInst & instruction,
1525 const auto operand1 =
ConvertValue(instruction.getArgOperand(0), tacs, context);
1526 const auto operand2 =
ConvertValue(instruction.getArgOperand(1), tacs, context);
1529 return tacs.back()->result(0);
1532static const Variable *
1534 const ::llvm::CallInst & instruction,
1538 const auto operand1 =
ConvertValue(instruction.getArgOperand(0), tacs, context);
1539 const auto operand2 =
ConvertValue(instruction.getArgOperand(1), tacs, context);
1542 return tacs.back()->result(0);
1545static const Variable *
1547 const ::llvm::CallInst & instruction,
1551 const auto operand1 =
ConvertValue(instruction.getArgOperand(0), tacs, context);
1552 const auto operand2 =
ConvertValue(instruction.getArgOperand(1), tacs, context);
1555 return tacs.back()->result(0);
1558static const Variable *
1560 const ::llvm::CallInst & instruction,
1564 const auto operand1 =
ConvertValue(instruction.getArgOperand(0), tacs, context);
1565 const auto operand2 =
ConvertValue(instruction.getArgOperand(1), tacs, context);
1568 return tacs.back()->result(0);
1571static const Variable *
1573 const ::llvm::CallInst & instruction,
1577 const auto operand1 =
ConvertValue(instruction.getArgOperand(0), tacs, context);
1578 const auto operand2 =
ConvertValue(instruction.getArgOperand(1), tacs, context);
1581 return tacs.back()->result(0);
1584static const Variable *
1586 const ::llvm::CallInst & instruction,
1590 const auto operand1 =
ConvertValue(instruction.getArgOperand(0), tacs, context);
1591 const auto operand2 =
ConvertValue(instruction.getArgOperand(1), tacs, context);
1594 return tacs.back()->result(0);
1597std::vector<const Variable *>
1599 const ::llvm::CallInst & callInstruction,
1603 const auto functionType = callInstruction.getFunctionType();
1605 std::vector<const Variable *>
arguments;
1606 for (
size_t n = 0; n < functionType->getNumParams(); n++)
1609 if (functionType->isVarArg())
1611 std::vector<const Variable *> variableArguments;
1612 for (
size_t n = functionType->getNumParams(); n < callInstruction.getNumOperands() - 1; n++)
1613 variableArguments.push_back(
1614 ConvertValue(callInstruction.getArgOperand(n), threeAddressCodes, context));
1617 arguments.push_back(threeAddressCodes.back()->result(0));
1626static const Variable *
1628 const ::llvm::CallInst & callInstruction,
1632 const auto functionType = callInstruction.getFunctionType();
1638 callInstruction.getAttributes(),
1639 callInstruction.arg_size(),
1649 if (is<PointerType>(*callee->
Type()))
1652 std::make_unique<PointerToFunctionOperation>(convertedFunctionType),
1654 callee = callee_cast->result(0);
1655 threeAddressCodes.push_back(std::move(callee_cast));
1657 else if (
auto fntype = std::dynamic_pointer_cast<const rvsdg::FunctionType>(callee->
Type()))
1662 if (*convertedFunctionType != *fntype)
1667 std::make_unique<FunctionToPointerOperation>(fntype),
1670 std::make_unique<PointerToFunctionOperation>(convertedFunctionType),
1671 { ptrCast->result(0) });
1672 callee = fnCast->result(0);
1673 threeAddressCodes.push_back(std::move(ptrCast));
1674 threeAddressCodes.push_back(std::move(fnCast));
1679 throw std::runtime_error(
"Unexpected callee type: " + callee->
Type()->debug_string());
1684 convertedFunctionType,
1686 std::move(attributes),
1689 const auto result = call->result(0);
1690 const auto ioState = call->result(call->nresults() - 2);
1691 const auto memoryState = call->result(call->nresults() - 1);
1693 threeAddressCodes.push_back(std::move(call));
1709 switch (intrinsicId)
1714 case ::llvm::Intrinsic::assume:
1715 case ::llvm::Intrinsic::expect:
1716 case ::llvm::Intrinsic::prefetch:
1720 case ::llvm::Intrinsic::lifetime_start:
1721 case ::llvm::Intrinsic::lifetime_end:
1724 case ::llvm::Intrinsic::experimental_noalias_scope_decl:
1732static const Variable *
1734 const ::llvm::IntrinsicInst & intrinsicInstruction,
1738 switch (
const auto intrinsicId = intrinsicInstruction.getIntrinsicID())
1740 case ::llvm::Intrinsic::abs:
1742 case ::llvm::Intrinsic::assume:
1747 case ::llvm::Intrinsic::bswap:
1749 case ::llvm::Intrinsic::ceil:
1751 case ::llvm::Intrinsic::copysign:
1753 case ::llvm::Intrinsic::ctlz:
1755 case ::llvm::Intrinsic::cttz:
1757 case ::llvm::Intrinsic::ctpop:
1759 case ::llvm::Intrinsic::expect:
1762 return ConvertValue(intrinsicInstruction.getArgOperand(0), threeAddressCodes, context);
1764 case ::llvm::Intrinsic::experimental_noalias_scope_decl:
1769 case ::llvm::Intrinsic::fabs:
1771 case ::llvm::Intrinsic::floor:
1773 case ::llvm::Intrinsic::fmuladd:
1775 case ::llvm::Intrinsic::fshl:
1777 case ::llvm::Intrinsic::is_constant:
1779 case ::llvm::Intrinsic::is_fpclass:
1781 case ::llvm::Intrinsic::lifetime_start:
1782 case ::llvm::Intrinsic::lifetime_end:
1787 case ::llvm::Intrinsic::memcpy:
1788 case ::llvm::Intrinsic::memcpy_inline:
1789 case ::llvm::Intrinsic::memcpy_element_unordered_atomic:
1791 case ::llvm::Intrinsic::memmove:
1792 case ::llvm::Intrinsic::memmove_element_unordered_atomic:
1794 case ::llvm::Intrinsic::memset:
1795 case ::llvm::Intrinsic::memset_inline:
1796 case ::llvm::Intrinsic::memset_element_unordered_atomic:
1798 case ::llvm::Intrinsic::prefetch:
1803 case ::llvm::Intrinsic::ptrmask:
1805 case ::llvm::Intrinsic::rint:
1807 case ::llvm::Intrinsic::round:
1809 case ::llvm::Intrinsic::sadd_with_overflow:
1811 case ::llvm::Intrinsic::smax:
1813 case ::llvm::Intrinsic::smul_with_overflow:
1815 case ::llvm::Intrinsic::smin:
1817 case ::llvm::Intrinsic::ssub_with_overflow:
1819 case ::llvm::Intrinsic::trunc:
1821 case ::llvm::Intrinsic::uadd_with_overflow:
1823 case ::llvm::Intrinsic::umax:
1825 case ::llvm::Intrinsic::umin:
1827 case ::llvm::Intrinsic::umul_with_overflow:
1832 return createCall(intrinsicInstruction, threeAddressCodes, context);
1837static const Variable *
1839 const ::llvm::CallInst & callInstruction,
1843 if (
const auto intrinsicInstruction = ::llvm::dyn_cast<::llvm::IntrinsicInst>(&callInstruction))
1852 return createCall(callInstruction, threeAddressCodes, context);
1855static inline const Variable *
1858 JLM_ASSERT(i->getOpcode() == ::llvm::Instruction::Select);
1859 auto instruction =
static_cast<::llvm::SelectInst *
>(i);
1861 auto p =
ConvertValue(instruction->getCondition(), tacs, ctx);
1862 auto t =
ConvertValue(instruction->getTrueValue(), tacs, ctx);
1863 auto f =
ConvertValue(instruction->getFalseValue(), tacs, ctx);
1865 if (i->getType()->isVectorTy())
1870 return tacs.back()->result(0);
1873static std::unique_ptr<rvsdg::BinaryOperation>
1875 const ::llvm::Instruction::BinaryOps binaryOperation,
1876 std::size_t numBits)
1878 switch (binaryOperation)
1880 case ::llvm::Instruction::Add:
1881 return std::make_unique<IntegerAddOperation>(numBits);
1882 case ::llvm::Instruction::And:
1883 return std::make_unique<IntegerAndOperation>(numBits);
1884 case ::llvm::Instruction::AShr:
1885 return std::make_unique<IntegerAShrOperation>(numBits);
1886 case ::llvm::Instruction::LShr:
1887 return std::make_unique<IntegerLShrOperation>(numBits);
1888 case ::llvm::Instruction::Mul:
1889 return std::make_unique<IntegerMulOperation>(numBits);
1890 case ::llvm::Instruction::Or:
1891 return std::make_unique<IntegerOrOperation>(numBits);
1892 case ::llvm::Instruction::SDiv:
1893 return std::make_unique<IntegerSDivOperation>(numBits);
1894 case ::llvm::Instruction::Shl:
1895 return std::make_unique<IntegerShlOperation>(numBits);
1896 case ::llvm::Instruction::SRem:
1897 return std::make_unique<IntegerSRemOperation>(numBits);
1898 case ::llvm::Instruction::Sub:
1899 return std::make_unique<IntegerSubOperation>(numBits);
1900 case ::llvm::Instruction::UDiv:
1901 return std::make_unique<IntegerUDivOperation>(numBits);
1902 case ::llvm::Instruction::URem:
1903 return std::make_unique<IntegerURemOperation>(numBits);
1904 case ::llvm::Instruction::Xor:
1905 return std::make_unique<IntegerXorOperation>(numBits);
1907 JLM_UNREACHABLE(
"ConvertIntegerBinaryOperation: Unsupported integer binary operation");
1911static std::unique_ptr<rvsdg::BinaryOperation>
1913 const ::llvm::Instruction::BinaryOps binaryOperation,
1914 fpsize floatingPointSize)
1916 switch (binaryOperation)
1918 case ::llvm::Instruction::FAdd:
1919 return std::make_unique<FBinaryOperation>(
fpop::add, floatingPointSize);
1920 case ::llvm::Instruction::FSub:
1921 return std::make_unique<FBinaryOperation>(
fpop::sub, floatingPointSize);
1922 case ::llvm::Instruction::FMul:
1923 return std::make_unique<FBinaryOperation>(
fpop::mul, floatingPointSize);
1924 case ::llvm::Instruction::FDiv:
1925 return std::make_unique<FBinaryOperation>(
fpop::div, floatingPointSize);
1926 case ::llvm::Instruction::FRem:
1927 return std::make_unique<FBinaryOperation>(
fpop::mod, floatingPointSize);
1929 JLM_UNREACHABLE(
"ConvertFloatingPointBinaryOperation: Unsupported binary operation");
1933static const Variable *
1936 const auto llvmType = instruction->getType();
1938 const auto opcode = instruction->getOpcode();
1940 std::unique_ptr<rvsdg::BinaryOperation> operation;
1941 if (llvmType->isVectorTy() && llvmType->getScalarType()->isIntegerTy())
1943 const auto numBits = llvmType->getScalarType()->getIntegerBitWidth();
1946 else if (llvmType->isVectorTy() && llvmType->getScalarType()->isFloatingPointTy())
1948 const auto size = typeConverter.ExtractFloatingPointSize(*llvmType->getScalarType());
1951 else if (llvmType->isIntegerTy())
1955 else if (llvmType->isFloatingPointTy())
1957 const auto size = typeConverter.ExtractFloatingPointSize(*llvmType);
1962 JLM_ASSERT(
"convert: Unhandled binary operation type.");
1965 const auto jlmType = typeConverter.ConvertLlvmType(*llvmType);
1966 auto operand1 =
ConvertValue(instruction->getOperand(0), tacs, ctx);
1967 auto operand2 =
ConvertValue(instruction->getOperand(1), tacs, ctx);
1969 if (instruction->getOpcode() == ::llvm::Instruction::SDiv
1970 || instruction->getOpcode() == ::llvm::Instruction::UDiv
1971 || instruction->getOpcode() == ::llvm::Instruction::SRem
1972 || instruction->getOpcode() == ::llvm::Instruction::URem)
1977 if (llvmType->isVectorTy())
1986 return tacs.back()->result(0);
1989static inline const Variable *
1992 JLM_ASSERT(instruction->getOpcode() == ::llvm::Instruction::Alloca);
1993 auto i =
static_cast<::llvm::AllocaInst *
>(instruction);
1996 auto size =
ConvertValue(i->getArraySize(), tacs, ctx);
1998 auto alignment = i->getAlign().value();
2001 auto result = tacs.back()->result(0);
2002 auto astate = tacs.back()->result(1);
2010static const Variable *
2013 JLM_ASSERT(i->getOpcode() == ::llvm::Instruction::ExtractValue);
2014 auto ev = ::llvm::dyn_cast<::llvm::ExtractValueInst>(i);
2019 return tacs.back()->result(0);
2022static const Variable *
2024 const ::llvm::InsertValueInst & instruction,
2028 const auto aggregateOperand =
ConvertValue(instruction.getOperand(0), tacs, context);
2029 const auto valueOperand =
ConvertValue(instruction.getOperand(1), tacs, context);
2034 return tacs.back()->result(0);
2037static inline const Variable *
2040 JLM_ASSERT(i->getOpcode() == ::llvm::Instruction::ExtractElement);
2042 auto vector =
ConvertValue(i->getOperand(0), tacs, ctx);
2043 auto index =
ConvertValue(i->getOperand(1), tacs, ctx);
2046 return tacs.back()->result(0);
2049static const Variable *
2055 std::vector<int> mask;
2056 for (
auto & element : i->getShuffleMask())
2057 mask.push_back(element);
2061 return tacs.back()->result(0);
2064static const Variable *
2067 JLM_ASSERT(i->getOpcode() == ::llvm::Instruction::InsertElement);
2069 auto vector =
ConvertValue(i->getOperand(0), tacs, ctx);
2070 auto value =
ConvertValue(i->getOperand(1), tacs, ctx);
2071 auto index =
ConvertValue(i->getOperand(2), tacs, ctx);
2074 return tacs.back()->result(0);
2077static const Variable *
2080 JLM_ASSERT(i->getOpcode() == ::llvm::Instruction::Freeze);
2082 auto operand =
ConvertValue(i->getOperand(0), tacs, ctx);
2085 return tacs.back()->result(0);
2088static const Variable *
2091 JLM_ASSERT(unaryOperator->getOpcode() == ::llvm::Instruction::FNeg);
2094 auto type = unaryOperator->getType();
2095 auto scalarType = typeConverter.
ConvertLlvmType(*type->getScalarType());
2096 auto operand =
ConvertValue(unaryOperator->getOperand(0), threeAddressCodeVector, ctx);
2098 if (type->isVectorTy())
2100 auto vectorType = typeConverter.ConvertLlvmType(*type);
2102 FNegOperation(std::static_pointer_cast<const FloatingPointType>(scalarType)),
2111 return threeAddressCodeVector.back()->result(0);
2115static std::unique_ptr<rvsdg::SimpleOperation>
2116create_unop(std::shared_ptr<const rvsdg::Type> st, std::shared_ptr<const rvsdg::Type> dt)
2118 return std::unique_ptr<rvsdg::SimpleOperation>(
new OP(std::move(st), std::move(dt)));
2121static const Variable *
2124 JLM_ASSERT(::llvm::dyn_cast<::llvm::CastInst>(i));
2126 auto st = i->getOperand(0)->getType();
2127 auto dt = i->getType();
2131 bool isLaneWiseCast =
false;
2132 if (i->getOpcode() != ::llvm::Instruction::BitCast)
2134 isLaneWiseCast = st->isVectorTy();
2135 JLM_ASSERT(st->isVectorTy() == dt->isVectorTy());
2138 static std::unordered_map<
2140 std::unique_ptr<rvsdg::SimpleOperation> (*)(
2141 std::shared_ptr<const rvsdg::Type>,
2142 std::shared_ptr<const rvsdg::Type>)>
2143 map({ { ::llvm::Instruction::Trunc, create_unop<TruncOperation> },
2144 { ::llvm::Instruction::ZExt, create_unop<ZExtOperation> },
2145 { ::llvm::Instruction::UIToFP, create_unop<UIToFPOperation> },
2146 { ::llvm::Instruction::SIToFP, create_unop<SIToFPOperation> },
2147 { ::llvm::Instruction::SExt, create_unop<SExtOperation> },
2148 { ::llvm::Instruction::PtrToInt, create_unop<PtrToIntOperation> },
2149 { ::llvm::Instruction::IntToPtr, create_unop<IntToPtrOperation> },
2150 { ::llvm::Instruction::FPTrunc, create_unop<FPTruncOperation> },
2151 { ::llvm::Instruction::FPToSI, create_unop<FPToSIOperation> },
2152 { ::llvm::Instruction::FPToUI, create_unop<FPToUIOperation> },
2153 { ::llvm::Instruction::FPExt, create_unop<FPExtOperation> },
2154 { ::llvm::Instruction::BitCast, create_unop<BitCastOperation> } });
2159 auto srctype = typeConverter.ConvertLlvmType(*(isLaneWiseCast ? st->getScalarType() : st));
2160 auto dsttype = typeConverter.ConvertLlvmType(*(isLaneWiseCast ? dt->getScalarType() : dt));
2162 JLM_ASSERT(map.find(i->getOpcode()) != map.end());
2163 auto unop = map[i->getOpcode()](std::move(srctype), std::move(dsttype));
2164 JLM_ASSERT(is<rvsdg::UnaryOperation>(*unop));
2172 return tacs.back()->result(0);
2175template<
class INSTRUCTIONTYPE>
2176static const Variable *
2179 JLM_ASSERT(::llvm::isa<INSTRUCTIONTYPE>(instruction));
2180 return convert(::llvm::cast<INSTRUCTIONTYPE>(instruction), tacs, ctx);
2183static const Variable *
2185 ::llvm::Instruction * instruction,
2186 std::vector<std::unique_ptr<ThreeAddressCode>> & threeAddressCodes,
2189 switch (instruction->getOpcode())
2191 case ::llvm::Instruction::Trunc:
2192 case ::llvm::Instruction::ZExt:
2193 case ::llvm::Instruction::UIToFP:
2194 case ::llvm::Instruction::SIToFP:
2195 case ::llvm::Instruction::SExt:
2196 case ::llvm::Instruction::PtrToInt:
2197 case ::llvm::Instruction::IntToPtr:
2198 case ::llvm::Instruction::FPTrunc:
2199 case ::llvm::Instruction::FPToSI:
2200 case ::llvm::Instruction::FPToUI:
2201 case ::llvm::Instruction::FPExt:
2202 case ::llvm::Instruction::BitCast:
2204 case ::llvm::Instruction::Add:
2205 case ::llvm::Instruction::And:
2206 case ::llvm::Instruction::AShr:
2207 case ::llvm::Instruction::Sub:
2208 case ::llvm::Instruction::UDiv:
2209 case ::llvm::Instruction::SDiv:
2210 case ::llvm::Instruction::URem:
2211 case ::llvm::Instruction::SRem:
2212 case ::llvm::Instruction::Shl:
2213 case ::llvm::Instruction::LShr:
2214 case ::llvm::Instruction::Or:
2215 case ::llvm::Instruction::Xor:
2216 case ::llvm::Instruction::Mul:
2217 case ::llvm::Instruction::FAdd:
2218 case ::llvm::Instruction::FSub:
2219 case ::llvm::Instruction::FMul:
2220 case ::llvm::Instruction::FDiv:
2221 case ::llvm::Instruction::FRem:
2222 return convert<::llvm::BinaryOperator>(instruction, threeAddressCodes, context);
2223 case ::llvm::Instruction::Ret:
2225 case ::llvm::Instruction::Br:
2227 case ::llvm::Instruction::Switch:
2229 ::llvm::cast<::llvm::SwitchInst>(instruction),
2232 case ::llvm::Instruction::Unreachable:
2234 case ::llvm::Instruction::FNeg:
2235 return convert<::llvm::UnaryOperator>(instruction, threeAddressCodes, context);
2236 case ::llvm::Instruction::ICmp:
2237 return convert<::llvm::ICmpInst>(instruction, threeAddressCodes, context);
2238 case ::llvm::Instruction::FCmp:
2240 case ::llvm::Instruction::Load:
2242 case ::llvm::Instruction::Store:
2244 case ::llvm::Instruction::PHI:
2246 case ::llvm::Instruction::GetElementPtr:
2248 case ::llvm::Instruction::Call:
2250 *::llvm::dyn_cast<::llvm::CallInst>(instruction),
2253 case ::llvm::Instruction::Select:
2255 case ::llvm::Instruction::Alloca:
2257 case ::llvm::Instruction::ExtractValue:
2259 case ::llvm::Instruction::InsertValue:
2261 *::llvm::dyn_cast<::llvm::InsertValueInst>(instruction),
2264 case ::llvm::Instruction::ExtractElement:
2266 case ::llvm::Instruction::ShuffleVector:
2267 return convert<::llvm::ShuffleVectorInst>(instruction, threeAddressCodes, context);
2268 case ::llvm::Instruction::InsertElement:
2270 case ::llvm::Instruction::Freeze:
2273 throw std::runtime_error(
util::strfmt(instruction->getOpcodeName(),
" is not supported."));
2277static std::vector<::llvm::PHINode *>
2280 std::vector<::llvm::PHINode *> phis;
2281 ::llvm::ReversePostOrderTraversal<::llvm::Function *> rpotraverser(&function);
2282 for (
auto & bb : rpotraverser)
2284 for (
auto & instruction : *bb)
2294 if (!tacs.empty() && is<SsaPhiOperation>(tacs.back()->operation()))
2296 auto phi = ::llvm::dyn_cast<::llvm::PHINode>(&instruction);
2297 phis.push_back(phi);
2315 for (
const auto & phi : phis)
2317 std::vector<ControlFlowGraphNode *> incomingNodes;
2318 std::vector<const Variable *> operands;
2319 for (
size_t n = 0; n < phi->getNumOperands(); n++)
2324 if (!ctx.
has(phi->getIncomingBlock(n)))
2330 auto predecessor = ctx.
get(phi->getIncomingBlock(n));
2331 if (std::find(incomingNodes.begin(), incomingNodes.end(), predecessor) != incomingNodes.end())
2336 operands.push_back(
ConvertValue(phi->getIncomingValue(n), tacs, ctx));
2338 incomingNodes.push_back(predecessor);
2343 auto phi_tac = util::assertedCast<const ThreeAddressCodeVariable>(ctx.
lookup_value(phi))->tac();
2345 SsaPhiOperation(std::move(incomingNodes), phi_tac->result(0)->Type()),
2354 ::llvm::ReversePostOrderTraversal<::llvm::Function *> rpotraverser(&f);
2355 for (
auto & bb : rpotraverser)
2361static std::unique_ptr<llvm::Argument>
2364 auto function = argument.getParent();
2365 auto name = argument.getName().str();
2368 function->getAttributes().getParamAttrs(argument.getArgNo()),
2377 auto exitNode = cfg.
exit();
2379 if (exitNode->NumInEdges() == 0)
2401 auto stronglyConnectedComponents =
find_sccs(cfg);
2402 for (
auto stronglyConnectedComponent : stronglyConnectedComponents)
2406 if (sccStructure->NumExitEdges() == 0)
2408 auto repetitionEdge = *sccStructure->RepetitionEdges().begin();
2412 auto op = std::make_unique<rvsdg::ControlConstantOperation>(
2418 basicBlock->add_outedge(exitNode);
2419 basicBlock->add_outedge(repetitionEdge->sink());
2421 repetitionEdge->divert(basicBlock);
2427 if (exitNode->NumInEdges() == 1)
2435 exitNode->divert_inedges(basicBlock);
2436 basicBlock->add_outedge(exitNode);
2439static std::unique_ptr<ControlFlowGraph>
2449 for (
const auto & arg : f.args())
2458 JLM_ASSERT(n < node->fcttype().NumArguments());
2459 auto & type = node->fcttype().Arguments()[n++];
2462 JLM_ASSERT(n < node->fcttype().NumArguments());
2464 auto & iotype = node->fcttype().Arguments()[n++];
2465 auto iostate = cfg.entry()->append_argument(
Argument::create(
"_io_", iotype));
2467 auto & memtype = node->fcttype().Arguments()[n++];
2468 auto memstate = cfg.entry()->append_argument(
Argument::create(
"_s_", memtype));
2470 JLM_ASSERT(n == node->fcttype().NumArguments());
2477 add_arguments(f, *cfg, ctx);
2482 cfg->exit()->divert_inedges(entry_block);
2483 entry_block->add_outedge(bbmap.LookupKey(&f.getEntryBlock()));
2487 if (!f.getReturnType()->isVoidTy())
2491 result = entry_block->last()->result(0);
2493 JLM_ASSERT(node->fcttype().NumResults() == 3);
2495 cfg->exit()->append_result(result);
2497 cfg->exit()->append_result(ctx.
iostate());
2518 if (function.isDeclaration())
2524 fv->function()->add_cfg(
create_cfg(function, ctx));
2531 static std::unordered_map<::llvm::GlobalValue::LinkageTypes, llvm::Linkage> map(
2533 { ::llvm::GlobalValue::AvailableExternallyLinkage,
2546 return map[linkage];
2552 auto create_data_node = [](const ::llvm::GlobalVariable & gv,
Context & ctx)
2554 auto name = gv.getName().str();
2555 auto constant = gv.isConstant();
2558 auto section = gv.getSection().str();
2559 const auto alignment = gv.getAlign().valueOrOne().value();
2571 auto create_function_node = [](const ::llvm::Function & f,
Context & ctx)
2573 auto name = f.getName().str();
2588 for (
auto & gv : lm.globals())
2590 auto node = create_data_node(gv, ctx);
2594 for (
auto & f : lm.getFunctionList())
2599 auto node = create_function_node(f, ctx);
2604static std::unique_ptr<DataNodeInit>
2607 if (!gv.hasInitializer())
2610 auto init = gv.getInitializer();
2613 return std::make_unique<DataNodeInit>(ctx.
lookup_value(init));
2615 return std::make_unique<DataNodeInit>(std::move(tacs));
2631 for (
auto & gv : lm.globals())
2634 for (
auto & f : lm.getFunctionList())
2638std::unique_ptr<InterProceduralGraphModule>
2643 llvmModule.getTargetTriple(),
2644 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< ThreeAddressCode > Create(const Variable *pointer, const Variable *iOState, const std::vector< const Variable * > &memoryStates)
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 * addMemoryHoistBarrier(tacsvector_t &tacs, const Variable *address, const Context &ctx)
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)