24 #include <llvm/ADT/PostOrderIterator.h>
25 #include <llvm/ADT/StringExtras.h>
26 #include <llvm/IR/BasicBlock.h>
27 #include <llvm/IR/Constants.h>
28 #include <llvm/IR/Function.h>
29 #include <llvm/IR/Instructions.h>
30 #include <llvm/IR/IntrinsicInst.h>
31 #include <llvm/IR/Intrinsics.h>
32 #include <llvm/IR/Module.h>
86 has(const ::llvm::BasicBlock * bb)
const noexcept
98 get(const ::llvm::BasicBlock * bb)
const noexcept
103 inline const ::llvm::BasicBlock *
112 bbmap_ = std::move(bbmap);
125 return vmap_.find(value)->second;
132 vmap_[value] = variable;
166 std::unordered_map<const ::llvm::Value *, const llvm::Variable *>
vmap_;
173 std::vector<std::unique_ptr<llvm::ThreeAddressCode>> &,
178 ::llvm::Instruction * instruction,
179 std::vector<std::unique_ptr<ThreeAddressCode>> & threeAddressCodes,
190 auto node = ctx.
node();
197 node->add_dependency(data->node());
203 if (
auto c = ::llvm::dyn_cast<::llvm::Constant>(v))
214 if (
auto fntype = std::dynamic_pointer_cast<const rvsdg::FunctionType>(var->
Type()))
216 auto operation = std::make_unique<FunctionToPointerOperation>(fntype);
217 std::unique_ptr<ThreeAddressCode> ptr_cast =
219 var = ptr_cast->result(0);
220 tacs.push_back(std::move(ptr_cast));
229 if (value.isNegative())
232 auto str = toString(value, 2,
false);
233 std::reverse(str.begin(), str.end());
236 if (value.isNegative())
237 vr = vr.
sext(value.getBitWidth() - str.size());
239 vr = vr.
zext(value.getBitWidth() - str.size());
247 typedef ::llvm::Attribute::AttrKind ak;
249 static std::unordered_map<::llvm::Attribute::AttrKind, Attribute::kind> map(
364 return { kind, attribute.getValueAsInt() };
372 if (attribute.getKindAsEnum() == ::llvm::Attribute::AttrKind::ByVal)
374 auto type = typeConverter.
ConvertLlvmType(*attribute.getValueAsType());
378 if (attribute.getKindAsEnum() == ::llvm::Attribute::AttrKind::StructRet)
380 auto type = typeConverter.
ConvertLlvmType(*attribute.getValueAsType());
387 static StringAttribute
391 return { attribute.getKindAsString().str(), attribute.getValueAsString().str() };
398 for (
auto & attribute : as)
400 if (attribute.isEnumAttribute())
404 else if (attribute.isIntAttribute())
408 else if (attribute.isTypeAttribute())
412 else if (attribute.isStringAttribute())
427 const ::llvm::AttributeList & attributeList,
428 const size_t numParameters,
431 auto returnAttributes =
convert_attributes(attributeList.getRetAttrs(), typeConverter);
432 auto functionAttributes =
convert_attributes(attributeList.getFnAttrs(), typeConverter);
434 std::vector<AttributeSet> parameterAttributes;
435 for (
size_t n = 0; n < numParameters; n++)
437 parameterAttributes.emplace_back(
442 std::move(functionAttributes),
443 std::move(returnAttributes),
444 std::move(parameterAttributes));
447 static const Variable *
449 ::llvm::Constant * c,
450 std::vector<std::unique_ptr<ThreeAddressCode>> & tacs,
453 JLM_ASSERT(c->getValueID() == ::llvm::Value::ConstantIntVal);
454 const auto constant = ::llvm::cast<const ::llvm::ConstantInt>(c);
460 return tacs.back()->result(0);
463 static inline const Variable *
465 ::llvm::Constant * c,
466 std::vector<std::unique_ptr<llvm::ThreeAddressCode>> & tacs,
469 JLM_ASSERT(c->getValueID() == ::llvm::Value::UndefValueVal);
474 return tacs.back()->result(0);
477 static const Variable *
479 ::llvm::Constant * constant,
480 std::vector<std::unique_ptr<llvm::ThreeAddressCode>> & tacs,
483 JLM_ASSERT(constant->getValueID() == ::llvm::Value::ConstantExprVal);
484 auto c = ::llvm::cast<::llvm::ConstantExpr>(constant);
496 auto instruction = c->getAsInstruction();
498 instruction->dropAllReferences();
502 static const Variable *
504 ::llvm::Constant * constant,
505 std::vector<std::unique_ptr<llvm::ThreeAddressCode>> & tacs,
508 JLM_ASSERT(constant->getValueID() == ::llvm::Value::ConstantFPVal);
509 auto c = ::llvm::cast<::llvm::ConstantFP>(constant);
514 return tacs.back()->result(0);
517 static const Variable *
519 ::llvm::Constant * c,
520 std::vector<std::unique_ptr<llvm::ThreeAddressCode>> & tacs,
523 JLM_ASSERT(c->getValueID() == ::llvm::Value::GlobalVariableVal);
527 static const Variable *
529 ::llvm::Constant * constant,
530 std::vector<std::unique_ptr<llvm::ThreeAddressCode>> & tacs,
533 JLM_ASSERT(::llvm::dyn_cast<const ::llvm::ConstantPointerNull>(constant));
534 auto & c = *::llvm::cast<const ::llvm::ConstantPointerNull>(constant);
539 return tacs.back()->result(0);
542 static const Variable *
544 ::llvm::Constant * constant,
545 std::vector<std::unique_ptr<llvm::ThreeAddressCode>> &,
548 JLM_ASSERT(constant->getValueID() == ::llvm::Value::BlockAddressVal);
553 static const Variable *
555 ::llvm::Constant * c,
556 std::vector<std::unique_ptr<llvm::ThreeAddressCode>> & tacs,
559 JLM_ASSERT(c->getValueID() == ::llvm::Value::ConstantAggregateZeroVal);
564 return tacs.back()->result(0);
567 static const Variable *
569 ::llvm::Constant * c,
570 std::vector<std::unique_ptr<llvm::ThreeAddressCode>> & tacs,
573 JLM_ASSERT(c->getValueID() == ::llvm::Value::ConstantArrayVal);
575 std::vector<const Variable *> elements;
576 for (
size_t n = 0; n < c->getNumOperands(); n++)
578 auto operand = c->getOperand(n);
579 JLM_ASSERT(::llvm::dyn_cast<const ::llvm::Constant>(operand));
580 auto constant = ::llvm::cast<::llvm::Constant>(operand);
586 return tacs.back()->result(0);
589 static const Variable *
591 ::llvm::Constant * constant,
592 std::vector<std::unique_ptr<llvm::ThreeAddressCode>> & tacs,
595 JLM_ASSERT(constant->getValueID() == ::llvm::Value::ConstantDataArrayVal);
596 const auto & c = *::llvm::cast<const ::llvm::ConstantDataArray>(constant);
598 std::vector<const Variable *> elements;
599 for (
size_t n = 0; n < c.getNumElements(); n++)
600 elements.push_back(
ConvertConstant(c.getElementAsConstant(n), tacs, ctx));
604 return tacs.back()->result(0);
607 static const Variable *
609 ::llvm::Constant * constant,
610 std::vector<std::unique_ptr<llvm::ThreeAddressCode>> & tacs,
613 JLM_ASSERT(constant->getValueID() == ::llvm::Value::ConstantDataVectorVal);
614 auto c = ::llvm::cast<const ::llvm::ConstantDataVector>(constant);
616 std::vector<const Variable *> elements;
617 for (
size_t n = 0; n < c->getNumElements(); n++)
618 elements.push_back(
ConvertConstant(c->getElementAsConstant(n), tacs, ctx));
622 return tacs.back()->result(0);
625 static const Variable *
627 ::llvm::Constant * c,
628 std::vector<std::unique_ptr<llvm::ThreeAddressCode>> & tacs,
631 JLM_ASSERT(c->getValueID() == ::llvm::Value::ConstantStructVal);
633 std::vector<const Variable *> elements;
634 for (
size_t n = 0; n < c->getNumOperands(); n++)
635 elements.push_back(
ConvertConstant(c->getAggregateElement(n), tacs, ctx));
640 return tacs.back()->result(0);
643 static const Variable *
645 ::llvm::Constant * c,
646 std::vector<std::unique_ptr<llvm::ThreeAddressCode>> & tacs,
649 JLM_ASSERT(c->getValueID() == ::llvm::Value::ConstantVectorVal);
651 std::vector<const Variable *> elements;
652 for (
size_t n = 0; n < c->getNumOperands(); n++)
653 elements.push_back(
ConvertConstant(c->getAggregateElement(n), tacs, ctx));
658 return tacs.back()->result(0);
661 static inline const Variable *
663 ::llvm::Constant * constant,
664 std::vector<std::unique_ptr<llvm::ThreeAddressCode>> &,
667 JLM_ASSERT(constant->getValueID() == ::llvm::Value::GlobalAliasVal);
672 static inline const Variable *
675 JLM_ASSERT(c->getValueID() == ::llvm::Value::FunctionVal);
679 static const Variable *
681 ::llvm::PoisonValue * poisonValue,
688 return threeAddressCodeVector.back()->result(0);
692 static const Variable *
694 ::llvm::Constant * constant,
699 return ConvertConstant(::llvm::cast<T>(constant), threeAddressCodeVector, context);
702 static const Variable *
704 ::llvm::Constant * c,
705 std::vector<std::unique_ptr<llvm::ThreeAddressCode>> & tacs,
708 static std::unordered_map<
710 const Variable * (*)(::llvm::Constant *,
711 std::vector<std::unique_ptr<llvm::ThreeAddressCode>> &,
727 { ::llvm::Value::PoisonValueVal, ConvertConstant<::llvm::PoisonValue> },
730 if (constantMap.find(c->getValueID()) != constantMap.end())
731 return constantMap[c->getValueID()](c, tacs, ctx);
736 static std::vector<std::unique_ptr<llvm::ThreeAddressCode>>
739 std::vector<std::unique_ptr<llvm::ThreeAddressCode>> tacs;
744 static inline const Variable *
747 JLM_ASSERT(instruction->getOpcode() == ::llvm::Instruction::Ret);
748 auto i = ::llvm::cast<::llvm::ReturnInst>(instruction);
750 auto bb = ctx.
get(i->getParent());
752 if (!i->getReturnValue())
755 auto value =
ConvertValue(i->getReturnValue(), tacs, ctx);
761 static const Variable *
764 JLM_ASSERT(instruction->getOpcode() == ::llvm::Instruction::Br);
765 auto i = ::llvm::cast<::llvm::BranchInst>(instruction);
766 auto bb = ctx.
get(i->getParent());
770 if (i->isUnconditional())
772 bb->add_outedge(ctx.
get(i->getSuccessor(0)));
776 bb->add_outedge(ctx.
get(i->getSuccessor(1)));
777 bb->add_outedge(ctx.
get(i->getSuccessor(0)));
780 auto nbits = i->getCondition()->getType()->getIntegerBitWidth();
789 static const Variable *
792 auto jlmSwitchBasicBlock = ctx.
get(switchInstruction->getParent());
794 JLM_ASSERT(jlmSwitchBasicBlock->NumOutEdges() == 0);
795 std::unordered_map<uint64_t, uint64_t> matchMapping;
796 std::unordered_map<::llvm::BasicBlock *, ControlFlowGraphEdge *> outEdgeMapping;
797 for (
auto caseIt = switchInstruction->case_begin(); caseIt != switchInstruction->case_end();
800 JLM_ASSERT(caseIt != switchInstruction->case_default());
801 auto llvmCaseBasicBlock = caseIt->getCaseSuccessor();
803 if (
auto outEdgeIt = outEdgeMapping.find(llvmCaseBasicBlock); outEdgeIt != outEdgeMapping.end())
807 matchMapping[caseIt->getCaseValue()->getZExtValue()] = outEdgeIt->second->index();
811 auto jlmCaseBasicBlock = ctx.
get(llvmCaseBasicBlock);
812 auto edge = jlmSwitchBasicBlock->
add_outedge(jlmCaseBasicBlock);
813 outEdgeMapping[llvmCaseBasicBlock] = edge;
814 matchMapping[caseIt->getCaseValue()->getZExtValue()] = edge->
index();
818 auto jlmDefaultBasicBlock = ctx.
get(switchInstruction->case_default()->getCaseSuccessor());
819 auto defaultEdge = jlmSwitchBasicBlock->
add_outedge(jlmDefaultBasicBlock);
821 auto c =
ConvertValue(switchInstruction->getCondition(), tacs, ctx);
822 auto numBits = switchInstruction->getCondition()->getType()->getIntegerBitWidth();
823 auto op = std::make_unique<rvsdg::MatchOperation>(
826 defaultEdge->index(),
827 jlmSwitchBasicBlock->NumOutEdges());
835 static inline const Variable *
838 JLM_ASSERT(i->getOpcode() == ::llvm::Instruction::Unreachable);
839 auto bb = ctx.
get(i->getParent());
844 static std::unique_ptr<rvsdg::BinaryOperation>
849 case ::llvm::CmpInst::ICMP_SLT:
850 return std::make_unique<IntegerSltOperation>(numBits);
851 case ::llvm::CmpInst::ICMP_ULT:
852 return std::make_unique<IntegerUltOperation>(numBits);
853 case ::llvm::CmpInst::ICMP_SLE:
854 return std::make_unique<IntegerSleOperation>(numBits);
855 case ::llvm::CmpInst::ICMP_ULE:
856 return std::make_unique<IntegerUleOperation>(numBits);
857 case ::llvm::CmpInst::ICMP_EQ:
858 return std::make_unique<IntegerEqOperation>(numBits);
859 case ::llvm::CmpInst::ICMP_NE:
860 return std::make_unique<IntegerNeOperation>(numBits);
861 case ::llvm::CmpInst::ICMP_SGE:
862 return std::make_unique<IntegerSgeOperation>(numBits);
863 case ::llvm::CmpInst::ICMP_UGE:
864 return std::make_unique<IntegerUgeOperation>(numBits);
865 case ::llvm::CmpInst::ICMP_SGT:
866 return std::make_unique<IntegerSgtOperation>(numBits);
867 case ::llvm::CmpInst::ICMP_UGT:
868 return std::make_unique<IntegerUgtOperation>(numBits);
870 JLM_UNREACHABLE(
"ConvertIntegerIcmpPredicate: Unsupported icmp predicate.");
874 static std::unique_ptr<rvsdg::BinaryOperation>
881 static const Variable *
884 const auto predicate = instruction->getPredicate();
885 const auto operandType = instruction->getOperand(0)->getType();
886 auto op1 =
ConvertValue(instruction->getOperand(0), tacs, ctx);
887 auto op2 =
ConvertValue(instruction->getOperand(1), tacs, ctx);
889 std::unique_ptr<rvsdg::BinaryOperation> operation;
890 if (operandType->isVectorTy() && operandType->getScalarType()->isIntegerTy())
895 else if (operandType->isVectorTy() && operandType->getScalarType()->isPointerTy())
899 else if (operandType->isIntegerTy())
903 else if (operandType->isPointerTy())
912 if (operandType->isVectorTy())
922 return tacs.back()->result(0);
925 static const Variable *
928 JLM_ASSERT(instruction->getOpcode() == ::llvm::Instruction::FCmp);
930 auto i = ::llvm::cast<const ::llvm::FCmpInst>(instruction);
931 auto t = i->getOperand(0)->getType();
933 static std::unordered_map<::llvm::CmpInst::Predicate, llvm::fpcmp> map(
951 auto type = typeConverter.ConvertLlvmType(*i->getType());
956 JLM_ASSERT(map.find(i->getPredicate()) != map.end());
957 auto fptype = t->isVectorTy() ? t->getScalarType() : t;
958 auto operation = std::make_unique<FCmpOperation>(
959 map[i->getPredicate()],
960 typeConverter.ExtractFloatingPointSize(*fptype));
967 return tacs.back()->result(0);
970 static const Variable *
973 auto ioBarrierOperation = std::make_unique<IOBarrierOperation>(operand->
Type());
976 return tacs.back()->result(0);
979 static inline const Variable *
982 JLM_ASSERT(i->getOpcode() == ::llvm::Instruction::Load);
983 auto instruction =
static_cast<::llvm::LoadInst *
>(i);
985 auto alignment = instruction->getAlign().value();
986 auto address =
ConvertValue(instruction->getPointerOperand(), tacs, ctx);
995 if (instruction->isVolatile())
1003 tacs.push_back(std::move(loadVolatileTac));
1005 loadedValue = tacs.back()->result(0);
1006 ioState = tacs.back()->result(1);
1007 memoryState = tacs.back()->result(2);
1014 tacs.push_back(std::move(loadTac));
1015 loadedValue = tacs.back()->result(0);
1016 memoryState = tacs.back()->result(1);
1028 static inline const Variable *
1031 JLM_ASSERT(i->getOpcode() == ::llvm::Instruction::Store);
1032 auto instruction =
static_cast<::llvm::StoreInst *
>(i);
1034 auto alignment = instruction->getAlign().value();
1035 auto address =
ConvertValue(instruction->getPointerOperand(), tacs, ctx);
1036 auto value =
ConvertValue(instruction->getValueOperand(), tacs, ctx);
1043 if (instruction->isVolatile())
1051 tacs.push_back(std::move(storeVolatileTac));
1052 ioState = tacs.back()->result(0);
1053 memoryState = tacs.back()->result(1);
1060 tacs.push_back(std::move(storeTac));
1061 memoryState = tacs.back()->result(0);
1073 static const Variable *
1082 return tacs.back()->result(0);
1085 static const Variable *
1088 JLM_ASSERT(::llvm::dyn_cast<const ::llvm::GetElementPtrInst>(inst));
1090 auto i = ::llvm::cast<::llvm::GetElementPtrInst>(inst);
1092 std::vector<const Variable *> indices;
1093 auto base =
ConvertValue(i->getPointerOperand(), tacs, ctx);
1094 for (
auto it = i->idx_begin(); it != i->idx_end(); it++)
1097 auto pointeeType = typeConverter.ConvertLlvmType(*i->getSourceElementType());
1101 return tacs.back()->result(0);
1104 static const Variable *
1106 const ::llvm::CallInst & instruction,
1111 const auto globalIOState = context.
iostate();
1113 const auto size =
ConvertValue(instruction.getArgOperand(0), threeAddressCodes, context);
1116 const auto mallocAddress = threeAddressCodes.back()->result(0);
1117 const auto mallocIOState = threeAddressCodes.back()->result(1);
1118 auto mallocMemoryState = threeAddressCodes.back()->result(2);
1122 threeAddressCodes.push_back(
1124 threeAddressCodes.push_back(
1127 return mallocAddress;
1130 static const Variable *
1132 const ::llvm::CallInst & instruction,
1136 const auto ioState = context.
iostate();
1139 const auto pointer =
ConvertValue(instruction.getArgOperand(0), threeAddressCodes, context);
1142 const auto & freeThreeAddressCode = *threeAddressCodes.back().get();
1144 threeAddressCodes.push_back(
1162 const auto constant = ::llvm::dyn_cast<const ::llvm::ConstantInt>(&value);
1163 JLM_ASSERT(constant !=
nullptr && constant->getType()->getIntegerBitWidth() == 1);
1165 const auto apInt = constant->getValue();
1168 return apInt.isOne();
1171 static const Variable *
1173 const ::llvm::IntrinsicInst * instruction,
1178 instruction->getIntrinsicID() == ::llvm::Intrinsic::memcpy
1179 || instruction->getIntrinsicID() == ::llvm::Intrinsic::memcpy_inline
1180 || instruction->getIntrinsicID() == ::llvm::Intrinsic::memcpy_element_unordered_atomic);
1182 if (instruction->getIntrinsicID() == ::llvm::Intrinsic::memcpy_inline)
1183 throw std::logic_error(
"Unhandled memcpy_inline intrinsic.");
1184 if (instruction->getIntrinsicID() == ::llvm::Intrinsic::memcpy_element_unordered_atomic)
1185 throw std::logic_error(
"Unhandled memcpy_element_unordered_atomic intrinsic.");
1187 const auto ioState = context.
iostate();
1190 const auto destination =
ConvertValue(instruction->getArgOperand(0), threeAddressCodes, context);
1191 const auto source =
ConvertValue(instruction->getArgOperand(1), threeAddressCodes, context);
1192 const auto length =
ConvertValue(instruction->getArgOperand(2), threeAddressCodes, context);
1194 if (
IsVolatile(*instruction->getArgOperand(3)))
1202 const auto & memCpyVolatileTac = *threeAddressCodes.back();
1204 threeAddressCodes.push_back(
1209 threeAddressCodes.push_back(
1211 threeAddressCodes.push_back(
1218 static const Variable *
1220 const ::llvm::IntrinsicInst & instruction,
1225 instruction.getIntrinsicID() == ::llvm::Intrinsic::memset
1226 || instruction.getIntrinsicID() == ::llvm::Intrinsic::memset_inline
1227 || instruction.getIntrinsicID() == ::llvm::Intrinsic::memset_element_unordered_atomic);
1229 if (instruction.getIntrinsicID() == ::llvm::Intrinsic::memset_inline)
1230 throw std::logic_error(
"Unhandled memset_inline intrinsic.");
1231 if (instruction.getIntrinsicID() == ::llvm::Intrinsic::memset_element_unordered_atomic)
1232 throw std::logic_error(
"Unhandled memset_element_unordered_atomic intrinsic.");
1236 const auto destination =
ConvertValue(instruction.getArgOperand(0), threeAddressCodes, context);
1237 const auto value =
ConvertValue(instruction.getArgOperand(1), threeAddressCodes, context);
1238 const auto length =
ConvertValue(instruction.getArgOperand(2), threeAddressCodes, context);
1240 if (
IsVolatile(*instruction.getArgOperand(3)))
1242 throw std::logic_error(
"Unhandled volatile memset intrinsic.");
1246 threeAddressCodes.push_back(
1248 threeAddressCodes.push_back(
1258 const auto function = callInstruction.getCalledFunction();
1259 return function &&
function->getName() ==
"malloc";
1265 const auto function = callInstruction.getCalledFunction();
1266 return function &&
function->getName() ==
"free";
1269 static const Variable *
1272 const auto multiplier =
ConvertValue(instruction.getArgOperand(0), tacs, ctx);
1273 const auto multiplicand =
ConvertValue(instruction.getArgOperand(1), tacs, ctx);
1274 const auto summand =
ConvertValue(instruction.getArgOperand(2), tacs, ctx);
1277 return tacs.back()->result(0);
1280 std::vector<const Variable *>
1282 const ::llvm::CallInst & callInstruction,
1286 const auto functionType = callInstruction.getFunctionType();
1288 std::vector<const Variable *> arguments;
1289 for (
size_t n = 0; n < functionType->getNumParams(); n++)
1290 arguments.push_back(
ConvertValue(callInstruction.getArgOperand(n), threeAddressCodes, context));
1292 if (functionType->isVarArg())
1294 std::vector<const Variable *> variableArguments;
1295 for (
size_t n = functionType->getNumParams(); n < callInstruction.getNumOperands() - 1; n++)
1296 variableArguments.push_back(
1297 ConvertValue(callInstruction.getArgOperand(n), threeAddressCodes, context));
1300 arguments.push_back(threeAddressCodes.back()->result(0));
1303 arguments.push_back(context.
iostate());
1309 static const Variable *
1311 const ::llvm::CallInst & callInstruction,
1315 const auto functionType = callInstruction.getFunctionType();
1321 callInstruction.getAttributes(),
1322 callInstruction.arg_size(),
1332 if (is<PointerType>(*callee->
Type()))
1335 std::make_unique<PointerToFunctionOperation>(convertedFunctionType),
1337 callee = callee_cast->result(0);
1338 threeAddressCodes.push_back(std::move(callee_cast));
1340 else if (
auto fntype = std::dynamic_pointer_cast<const rvsdg::FunctionType>(callee->
Type()))
1345 if (*convertedFunctionType != *fntype)
1350 std::make_unique<FunctionToPointerOperation>(fntype),
1353 std::make_unique<PointerToFunctionOperation>(convertedFunctionType),
1354 { ptrCast->result(0) });
1355 callee = fnCast->result(0);
1356 threeAddressCodes.push_back(std::move(ptrCast));
1357 threeAddressCodes.push_back(std::move(fnCast));
1362 throw std::runtime_error(
"Unexpected callee type: " + callee->
Type()->debug_string());
1367 convertedFunctionType,
1369 std::move(attributes),
1372 const auto result = call->result(0);
1373 const auto ioState = call->result(call->nresults() - 2);
1374 const auto memoryState = call->result(call->nresults() - 1);
1376 threeAddressCodes.push_back(std::move(call));
1392 switch (intrinsicId)
1396 case ::llvm::Intrinsic::lifetime_start:
1397 case ::llvm::Intrinsic::lifetime_end:
1399 case ::llvm::Intrinsic::experimental_noalias_scope_decl:
1406 static const Variable *
1408 const ::llvm::IntrinsicInst & intrinsicInstruction,
1415 switch (intrinsicInstruction.getIntrinsicID())
1417 case ::llvm::Intrinsic::fmuladd:
1419 case ::llvm::Intrinsic::memcpy:
1420 case ::llvm::Intrinsic::memcpy_inline:
1421 case ::llvm::Intrinsic::memcpy_element_unordered_atomic:
1423 case ::llvm::Intrinsic::memset:
1424 case ::llvm::Intrinsic::memset_inline:
1425 case ::llvm::Intrinsic::memset_element_unordered_atomic:
1428 return createCall(intrinsicInstruction, threeAddressCodes, context);
1432 static const Variable *
1434 const ::llvm::CallInst & callInstruction,
1438 if (
const auto intrinsicInstruction = ::llvm::dyn_cast<::llvm::IntrinsicInst>(&callInstruction))
1447 return createCall(callInstruction, threeAddressCodes, context);
1450 static inline const Variable *
1453 JLM_ASSERT(i->getOpcode() == ::llvm::Instruction::Select);
1454 auto instruction =
static_cast<::llvm::SelectInst *
>(i);
1456 auto p =
ConvertValue(instruction->getCondition(), tacs, ctx);
1457 auto t =
ConvertValue(instruction->getTrueValue(), tacs, ctx);
1458 auto f =
ConvertValue(instruction->getFalseValue(), tacs, ctx);
1460 if (i->getType()->isVectorTy())
1465 return tacs.back()->result(0);
1468 static std::unique_ptr<rvsdg::BinaryOperation>
1470 const ::llvm::Instruction::BinaryOps binaryOperation,
1471 std::size_t numBits)
1473 switch (binaryOperation)
1475 case ::llvm::Instruction::Add:
1476 return std::make_unique<IntegerAddOperation>(numBits);
1477 case ::llvm::Instruction::And:
1478 return std::make_unique<IntegerAndOperation>(numBits);
1479 case ::llvm::Instruction::AShr:
1480 return std::make_unique<IntegerAShrOperation>(numBits);
1481 case ::llvm::Instruction::LShr:
1482 return std::make_unique<IntegerLShrOperation>(numBits);
1483 case ::llvm::Instruction::Mul:
1484 return std::make_unique<IntegerMulOperation>(numBits);
1485 case ::llvm::Instruction::Or:
1486 return std::make_unique<IntegerOrOperation>(numBits);
1487 case ::llvm::Instruction::SDiv:
1488 return std::make_unique<IntegerSDivOperation>(numBits);
1489 case ::llvm::Instruction::Shl:
1490 return std::make_unique<IntegerShlOperation>(numBits);
1491 case ::llvm::Instruction::SRem:
1492 return std::make_unique<IntegerSRemOperation>(numBits);
1493 case ::llvm::Instruction::Sub:
1494 return std::make_unique<IntegerSubOperation>(numBits);
1495 case ::llvm::Instruction::UDiv:
1496 return std::make_unique<IntegerUDivOperation>(numBits);
1497 case ::llvm::Instruction::URem:
1498 return std::make_unique<IntegerURemOperation>(numBits);
1499 case ::llvm::Instruction::Xor:
1500 return std::make_unique<IntegerXorOperation>(numBits);
1502 JLM_UNREACHABLE(
"ConvertIntegerBinaryOperation: Unsupported integer binary operation");
1506 static std::unique_ptr<rvsdg::BinaryOperation>
1508 const ::llvm::Instruction::BinaryOps binaryOperation,
1509 fpsize floatingPointSize)
1511 switch (binaryOperation)
1513 case ::llvm::Instruction::FAdd:
1514 return std::make_unique<FBinaryOperation>(
fpop::add, floatingPointSize);
1515 case ::llvm::Instruction::FSub:
1516 return std::make_unique<FBinaryOperation>(
fpop::sub, floatingPointSize);
1517 case ::llvm::Instruction::FMul:
1518 return std::make_unique<FBinaryOperation>(
fpop::mul, floatingPointSize);
1519 case ::llvm::Instruction::FDiv:
1520 return std::make_unique<FBinaryOperation>(
fpop::div, floatingPointSize);
1521 case ::llvm::Instruction::FRem:
1522 return std::make_unique<FBinaryOperation>(
fpop::mod, floatingPointSize);
1524 JLM_UNREACHABLE(
"ConvertFloatingPointBinaryOperation: Unsupported binary operation");
1528 static const Variable *
1531 const auto llvmType = instruction->getType();
1533 const auto opcode = instruction->getOpcode();
1535 std::unique_ptr<rvsdg::BinaryOperation> operation;
1536 if (llvmType->isVectorTy() && llvmType->getScalarType()->isIntegerTy())
1538 const auto numBits = llvmType->getScalarType()->getIntegerBitWidth();
1541 else if (llvmType->isVectorTy() && llvmType->getScalarType()->isFloatingPointTy())
1543 const auto size = typeConverter.ExtractFloatingPointSize(*llvmType->getScalarType());
1546 else if (llvmType->isIntegerTy())
1550 else if (llvmType->isFloatingPointTy())
1552 const auto size = typeConverter.ExtractFloatingPointSize(*llvmType);
1557 JLM_ASSERT(
"convert: Unhandled binary operation type.");
1560 const auto jlmType = typeConverter.ConvertLlvmType(*llvmType);
1561 auto operand1 =
ConvertValue(instruction->getOperand(0), tacs, ctx);
1562 auto operand2 =
ConvertValue(instruction->getOperand(1), tacs, ctx);
1564 if (instruction->getOpcode() == ::llvm::Instruction::SDiv
1565 || instruction->getOpcode() == ::llvm::Instruction::UDiv
1566 || instruction->getOpcode() == ::llvm::Instruction::SRem
1567 || instruction->getOpcode() == ::llvm::Instruction::URem)
1572 if (llvmType->isVectorTy())
1581 return tacs.back()->result(0);
1584 static inline const Variable *
1587 JLM_ASSERT(instruction->getOpcode() == ::llvm::Instruction::Alloca);
1588 auto i =
static_cast<::llvm::AllocaInst *
>(instruction);
1591 auto size =
ConvertValue(i->getArraySize(), tacs, ctx);
1593 auto alignment = i->getAlign().value();
1596 auto result = tacs.back()->result(0);
1597 auto astate = tacs.back()->result(1);
1605 static const Variable *
1608 JLM_ASSERT(i->getOpcode() == ::llvm::Instruction::ExtractValue);
1609 auto ev = ::llvm::dyn_cast<::llvm::ExtractValueInst>(i);
1614 return tacs.back()->result(0);
1617 static const Variable *
1619 const ::llvm::InsertValueInst & instruction,
1623 const auto aggregateOperand =
ConvertValue(instruction.getOperand(0), tacs, context);
1624 const auto valueOperand =
ConvertValue(instruction.getOperand(1), tacs, context);
1629 return tacs.back()->result(0);
1632 static inline const Variable *
1635 JLM_ASSERT(i->getOpcode() == ::llvm::Instruction::ExtractElement);
1637 auto vector =
ConvertValue(i->getOperand(0), tacs, ctx);
1638 auto index =
ConvertValue(i->getOperand(1), tacs, ctx);
1641 return tacs.back()->result(0);
1644 static const Variable *
1650 std::vector<int> mask;
1651 for (
auto & element : i->getShuffleMask())
1652 mask.push_back(element);
1656 return tacs.back()->result(0);
1659 static const Variable *
1662 JLM_ASSERT(i->getOpcode() == ::llvm::Instruction::InsertElement);
1664 auto vector =
ConvertValue(i->getOperand(0), tacs, ctx);
1665 auto value =
ConvertValue(i->getOperand(1), tacs, ctx);
1666 auto index =
ConvertValue(i->getOperand(2), tacs, ctx);
1669 return tacs.back()->result(0);
1672 static const Variable *
1675 JLM_ASSERT(i->getOpcode() == ::llvm::Instruction::Freeze);
1677 auto operand =
ConvertValue(i->getOperand(0), tacs, ctx);
1680 return tacs.back()->result(0);
1683 static const Variable *
1686 JLM_ASSERT(unaryOperator->getOpcode() == ::llvm::Instruction::FNeg);
1689 auto type = unaryOperator->getType();
1690 auto scalarType = typeConverter.
ConvertLlvmType(*type->getScalarType());
1691 auto operand =
ConvertValue(unaryOperator->getOperand(0), threeAddressCodeVector, ctx);
1693 if (type->isVectorTy())
1695 auto vectorType = typeConverter.ConvertLlvmType(*type);
1697 FNegOperation(std::static_pointer_cast<const FloatingPointType>(scalarType)),
1706 return threeAddressCodeVector.back()->result(0);
1710 static std::unique_ptr<rvsdg::SimpleOperation>
1711 create_unop(std::shared_ptr<const rvsdg::Type> st, std::shared_ptr<const rvsdg::Type> dt)
1713 return std::unique_ptr<rvsdg::SimpleOperation>(
new OP(std::move(st), std::move(dt)));
1716 static const Variable *
1719 JLM_ASSERT(::llvm::dyn_cast<::llvm::CastInst>(i));
1721 auto st = i->getOperand(0)->getType();
1722 auto dt = i->getType();
1726 bool isLaneWiseCast =
false;
1727 if (i->getOpcode() != ::llvm::Instruction::BitCast)
1729 isLaneWiseCast = st->isVectorTy();
1730 JLM_ASSERT(st->isVectorTy() == dt->isVectorTy());
1733 static std::unordered_map<
1735 std::unique_ptr<rvsdg::SimpleOperation> (*)(
1736 std::shared_ptr<const rvsdg::Type>,
1737 std::shared_ptr<const rvsdg::Type>)>
1738 map({ { ::llvm::Instruction::Trunc, create_unop<TruncOperation> },
1739 { ::llvm::Instruction::ZExt, create_unop<ZExtOperation> },
1740 { ::llvm::Instruction::UIToFP, create_unop<UIToFPOperation> },
1741 { ::llvm::Instruction::SIToFP, create_unop<SIToFPOperation> },
1742 { ::llvm::Instruction::SExt, create_unop<SExtOperation> },
1743 { ::llvm::Instruction::PtrToInt, create_unop<PtrToIntOperation> },
1744 { ::llvm::Instruction::IntToPtr, create_unop<IntegerToPointerOperation> },
1745 { ::llvm::Instruction::FPTrunc, create_unop<FPTruncOperation> },
1746 { ::llvm::Instruction::FPToSI, create_unop<FloatingPointToSignedIntegerOperation> },
1747 { ::llvm::Instruction::FPToUI, create_unop<FloatingPointToUnsignedIntegerOperation> },
1748 { ::llvm::Instruction::FPExt, create_unop<FPExtOperation> },
1749 { ::llvm::Instruction::BitCast, create_unop<BitCastOperation> } });
1754 auto srctype = typeConverter.ConvertLlvmType(*(isLaneWiseCast ? st->getScalarType() : st));
1755 auto dsttype = typeConverter.ConvertLlvmType(*(isLaneWiseCast ? dt->getScalarType() : dt));
1757 JLM_ASSERT(map.find(i->getOpcode()) != map.end());
1758 auto unop = map[i->getOpcode()](std::move(srctype), std::move(dsttype));
1759 JLM_ASSERT(is<rvsdg::UnaryOperation>(*unop));
1767 return tacs.back()->result(0);
1770 template<
class INSTRUCTIONTYPE>
1771 static const Variable *
1774 JLM_ASSERT(::llvm::isa<INSTRUCTIONTYPE>(instruction));
1775 return convert(::llvm::cast<INSTRUCTIONTYPE>(instruction), tacs, ctx);
1778 static const Variable *
1780 ::llvm::Instruction * instruction,
1781 std::vector<std::unique_ptr<ThreeAddressCode>> & threeAddressCodes,
1784 switch (instruction->getOpcode())
1786 case ::llvm::Instruction::Trunc:
1787 case ::llvm::Instruction::ZExt:
1788 case ::llvm::Instruction::UIToFP:
1789 case ::llvm::Instruction::SIToFP:
1790 case ::llvm::Instruction::SExt:
1791 case ::llvm::Instruction::PtrToInt:
1792 case ::llvm::Instruction::IntToPtr:
1793 case ::llvm::Instruction::FPTrunc:
1794 case ::llvm::Instruction::FPToSI:
1795 case ::llvm::Instruction::FPToUI:
1796 case ::llvm::Instruction::FPExt:
1797 case ::llvm::Instruction::BitCast:
1799 case ::llvm::Instruction::Add:
1800 case ::llvm::Instruction::And:
1801 case ::llvm::Instruction::AShr:
1802 case ::llvm::Instruction::Sub:
1803 case ::llvm::Instruction::UDiv:
1804 case ::llvm::Instruction::SDiv:
1805 case ::llvm::Instruction::URem:
1806 case ::llvm::Instruction::SRem:
1807 case ::llvm::Instruction::Shl:
1808 case ::llvm::Instruction::LShr:
1809 case ::llvm::Instruction::Or:
1810 case ::llvm::Instruction::Xor:
1811 case ::llvm::Instruction::Mul:
1812 case ::llvm::Instruction::FAdd:
1813 case ::llvm::Instruction::FSub:
1814 case ::llvm::Instruction::FMul:
1815 case ::llvm::Instruction::FDiv:
1816 case ::llvm::Instruction::FRem:
1817 return convert<::llvm::BinaryOperator>(instruction, threeAddressCodes, context);
1818 case ::llvm::Instruction::Ret:
1820 case ::llvm::Instruction::Br:
1822 case ::llvm::Instruction::Switch:
1824 ::llvm::cast<::llvm::SwitchInst>(instruction),
1827 case ::llvm::Instruction::Unreachable:
1829 case ::llvm::Instruction::FNeg:
1830 return convert<::llvm::UnaryOperator>(instruction, threeAddressCodes, context);
1831 case ::llvm::Instruction::ICmp:
1832 return convert<::llvm::ICmpInst>(instruction, threeAddressCodes, context);
1833 case ::llvm::Instruction::FCmp:
1835 case ::llvm::Instruction::Load:
1837 case ::llvm::Instruction::Store:
1839 case ::llvm::Instruction::PHI:
1841 case ::llvm::Instruction::GetElementPtr:
1843 case ::llvm::Instruction::Call:
1845 *::llvm::dyn_cast<::llvm::CallInst>(instruction),
1848 case ::llvm::Instruction::Select:
1850 case ::llvm::Instruction::Alloca:
1852 case ::llvm::Instruction::ExtractValue:
1854 case ::llvm::Instruction::InsertValue:
1856 *::llvm::dyn_cast<::llvm::InsertValueInst>(instruction),
1859 case ::llvm::Instruction::ExtractElement:
1861 case ::llvm::Instruction::ShuffleVector:
1862 return convert<::llvm::ShuffleVectorInst>(instruction, threeAddressCodes, context);
1863 case ::llvm::Instruction::InsertElement:
1865 case ::llvm::Instruction::Freeze:
1868 throw std::runtime_error(
util::strfmt(instruction->getOpcodeName(),
" is not supported."));
1872 static std::vector<::llvm::PHINode *>
1875 std::vector<::llvm::PHINode *> phis;
1876 ::llvm::ReversePostOrderTraversal<::llvm::Function *> rpotraverser(&
function);
1877 for (
auto & bb : rpotraverser)
1879 for (
auto & instruction : *bb)
1889 if (!tacs.empty() && is<SsaPhiOperation>(tacs.back()->operation()))
1891 auto phi = ::llvm::dyn_cast<::llvm::PHINode>(&instruction);
1892 phis.push_back(phi);
1910 for (
const auto & phi : phis)
1912 std::vector<ControlFlowGraphNode *> incomingNodes;
1913 std::vector<const Variable *>
operands;
1914 for (
size_t n = 0; n < phi->getNumOperands(); n++)
1919 if (!ctx.
has(phi->getIncomingBlock(n)))
1925 auto predecessor = ctx.
get(phi->getIncomingBlock(n));
1926 if (std::find(incomingNodes.begin(), incomingNodes.end(), predecessor) != incomingNodes.end())
1932 predecessor->insert_before_branch(tacs);
1933 incomingNodes.push_back(predecessor);
1938 auto phi_tac = util::assertedCast<const ThreeAddressCodeVariable>(ctx.
lookup_value(phi))->tac();
1940 SsaPhiOperation(std::move(incomingNodes), phi_tac->result(0)->Type()),
1949 ::llvm::ReversePostOrderTraversal<::llvm::Function *> rpotraverser(&f);
1950 for (
auto & bb : rpotraverser)
1956 static std::unique_ptr<llvm::Argument>
1959 auto function = argument.getParent();
1960 auto name = argument.getName().str();
1963 function->getAttributes().getParamAttrs(argument.getArgNo()),
1972 auto exitNode = cfg.
exit();
1974 if (exitNode->NumInEdges() == 0)
1996 auto stronglyConnectedComponents =
find_sccs(cfg);
1997 for (
auto stronglyConnectedComponent : stronglyConnectedComponents)
2001 if (sccStructure->NumExitEdges() == 0)
2003 auto repetitionEdge = *sccStructure->RepetitionEdges().begin();
2007 auto op = std::make_unique<rvsdg::ControlConstantOperation>(
2013 basicBlock->add_outedge(exitNode);
2014 basicBlock->add_outedge(repetitionEdge->sink());
2016 repetitionEdge->divert(basicBlock);
2022 if (exitNode->NumInEdges() == 1)
2030 exitNode->divert_inedges(basicBlock);
2031 basicBlock->add_outedge(exitNode);
2034 static std::unique_ptr<ControlFlowGraph>
2044 for (
const auto & arg : f.args())
2053 JLM_ASSERT(n < node->fcttype().NumArguments());
2054 auto & type = node->fcttype().Arguments()[n++];
2057 JLM_ASSERT(n < node->fcttype().NumArguments());
2059 auto & iotype = node->fcttype().Arguments()[n++];
2060 auto iostate = cfg.entry()->append_argument(
Argument::create(
"_io_", iotype));
2062 auto & memtype = node->fcttype().Arguments()[n++];
2063 auto memstate = cfg.entry()->append_argument(
Argument::create(
"_s_", memtype));
2065 JLM_ASSERT(n == node->fcttype().NumArguments());
2072 add_arguments(f, *cfg, ctx);
2077 cfg->exit()->divert_inedges(entry_block);
2078 entry_block->add_outedge(bbmap.LookupKey(&f.getEntryBlock()));
2082 if (!f.getReturnType()->isVoidTy())
2086 result = entry_block->last()->result(0);
2088 JLM_ASSERT(node->fcttype().NumResults() == 3);
2090 cfg->exit()->append_result(result);
2092 cfg->exit()->append_result(ctx.
iostate());
2113 if (
function.isDeclaration())
2119 fv->function()->add_cfg(
create_cfg(
function, ctx));
2126 static std::unordered_map<::llvm::GlobalValue::LinkageTypes, llvm::Linkage> map(
2128 { ::llvm::GlobalValue::AvailableExternallyLinkage,
2141 return map[linkage];
2147 auto create_data_node = [](const ::llvm::GlobalVariable & gv,
Context & ctx)
2149 auto name = gv.getName().str();
2150 auto constant = gv.isConstant();
2153 auto section = gv.getSection().str();
2154 const auto alignment = gv.getAlign().valueOrOne().value();
2166 auto create_function_node = [](const ::llvm::Function & f,
Context & ctx)
2168 auto name = f.getName().str();
2183 for (
auto & gv : lm.globals())
2185 auto node = create_data_node(gv, ctx);
2189 for (
auto & f : lm.getFunctionList())
2194 auto node = create_function_node(f, ctx);
2199 static std::unique_ptr<DataNodeInit>
2202 if (!gv.hasInitializer())
2205 auto init = gv.getInitializer();
2208 return std::make_unique<DataNodeInit>(ctx.
lookup_value(init));
2210 return std::make_unique<DataNodeInit>(std::move(tacs));
2226 for (
auto & gv : lm.globals())
2229 for (
auto & f : lm.getFunctionList())
2233 std::unique_ptr<InterProceduralGraphModule>
2238 llvmModule.getTargetTriple(),
2239 llvmModule.getDataLayoutStr());
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 BasicBlock * create(ControlFlowGraph &cfg)
llvm::ThreeAddressCode * append_last(std::unique_ptr< llvm::ThreeAddressCode > tac)
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< 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< 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< llvm::ThreeAddressCode > create(const ::llvm::APFloat &constant, const std::shared_ptr< const jlm::rvsdg::Type > &type)
static std::unique_ptr< llvm::ThreeAddressCode > Create(std::shared_ptr< const rvsdg::Type > type)
static std::unique_ptr< llvm::ThreeAddressCode > create(const std::vector< const Variable * > &elements, const std::shared_ptr< const jlm::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::BasicBlock * get(BasicBlock *bb) const noexcept
Context(InterProceduralGraphModule &im)
const llvm::Variable * lookup_value(const ::llvm::Value *value) const noexcept
llvm::Variable * memory_state() const noexcept
const llvm::Variable * result() const noexcept
bool has_value(const ::llvm::Value *value) const noexcept
llvm::Variable * iostate() const noexcept
const llvm::Variable * result_
void set_memory_state(llvm::Variable *state)
InterProceduralGraphModule & module() const noexcept
void set_iostate(llvm::Variable *state)
void set_result(const llvm::Variable *result)
TypeConverter TypeConverter_
void set_basic_block_map(BasicBlockMap bbmap)
BasicBlock * get(const ::llvm::BasicBlock *bb) const noexcept
InterProceduralGraphNode * node() const noexcept
void set_node(InterProceduralGraphNode *node) noexcept
llvm::Variable * memory_state_
bool has(BasicBlock *bb) const noexcept
std::unordered_map< const ::llvm::Value *, const llvm::Variable * > vmap_
llvm::Variable * iostate_
void insert_value(const ::llvm::Value *value, const llvm::Variable *variable)
TypeConverter & GetTypeConverter() noexcept
bool has(const ::llvm::BasicBlock *bb) const noexcept
InterProceduralGraphNode * node_
InterProceduralGraphModule & module_
size_t index() const noexcept
ControlFlowGraphEdge * add_outedge(ControlFlowGraphNode *sink)
static std::unique_ptr< ControlFlowGraph > create(InterProceduralGraphModule &im)
ExitNode * exit() const noexcept
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 &multiplier, const Variable &multiplicand, const Variable &summand)
static std::unique_ptr< llvm::ThreeAddressCode > create(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 > pointeeType)
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)
llvm::Variable * create_variable(std::shared_ptr< const jlm::rvsdg::Type > type, const std::string &name)
GlobalValue * create_global_value(DataNode *node)
static std::unique_ptr< InterProceduralGraphModule > create(const jlm::util::FilePath &sourceFilename, const std::string &targetTriple, const std::string &dataLayout)
InterProceduralGraph & ipgraph() noexcept
void add_dependency(const InterProceduralGraphNode *dep)
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 &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< 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)
::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 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 * convertInstruction(::llvm::Instruction *instruction, std::vector< std::unique_ptr< ThreeAddressCode >> &threeAddressCodes, Context &context)
static const Variable * convert_fcmp_instruction(::llvm::Instruction *instruction, tacsvector_t &tacs, Context &ctx)
static rvsdg::BitValueRepresentation convert_apint(const ::llvm::APInt &value)
static void convert_globals(::llvm::Module &lm, Context &ctx)
static const Variable * convert_constantFP(::llvm::Constant *constant, std::vector< std::unique_ptr< llvm::ThreeAddressCode >> &tacs, Context &ctx)
static std::unique_ptr< rvsdg::SimpleOperation > create_unop(std::shared_ptr< const rvsdg::Type > st, std::shared_ptr< const rvsdg::Type > dt)
ICmpPredicate convertICmpPredicateToJlm(::llvm::CmpInst::Predicate predicate)
std::vector< StronglyConnectedComponent > find_sccs(const ControlFlowGraph &cfg)
static ControlFlowGraphNode * aggregate(ControlFlowGraphNode *, ControlFlowGraphNode *, AggregationMap &)
static const Variable * convert_insertelement_instruction(::llvm::Instruction *i, tacsvector_t &tacs, Context &ctx)
static bool shouldIgnoreIntrinsic(::llvm::Intrinsic::ID intrinsicId)
static const Variable * convertMemSetCall(const ::llvm::IntrinsicInst &instruction, tacsvector_t &threeAddressCodes, Context &context)
static IntAttribute ConvertIntAttribute(const ::llvm::Attribute &attribute)
static const Variable * convert_globalAlias(::llvm::Constant *constant, std::vector< std::unique_ptr< llvm::ThreeAddressCode >> &, Context &)
std::vector< std::unique_ptr< llvm::ThreeAddressCode > > tacsvector_t
static const Variable * AddIOBarrier(tacsvector_t &tacs, const Variable *operand, const Context &ctx)
static const Variable * convert_globalVariable(::llvm::Constant *c, std::vector< std::unique_ptr< llvm::ThreeAddressCode >> &tacs, Context &ctx)
std::vector< const Variable * > convertCallArguments(const ::llvm::CallInst &callInstruction, tacsvector_t &threeAddressCodes, Context &context)
static BasicBlockMap convert_basic_blocks(::llvm::Function &f, ControlFlowGraph &cfg)
static const Variable * convert_extractvalue(::llvm::Instruction *i, tacsvector_t &tacs, Context &ctx)
static const Variable * convertMallocCall(const ::llvm::CallInst &instruction, tacsvector_t &threeAddressCodes, Context &context)
static std::unique_ptr< rvsdg::BinaryOperation > ConvertFloatingPointBinaryOperation(const ::llvm::Instruction::BinaryOps binaryOperation, fpsize floatingPointSize)
static const Variable * convert_constantAggregateZero(::llvm::Constant *c, std::vector< std::unique_ptr< llvm::ThreeAddressCode >> &tacs, Context &ctx)
static TypeAttribute ConvertTypeAttribute(const ::llvm::Attribute &attribute, TypeConverter &typeConverter)
static std::unique_ptr< DataNodeInit > create_initialization(::llvm::GlobalVariable &gv, Context &ctx)
static const Variable * convert_extractelement_instruction(::llvm::Instruction *i, tacsvector_t &tacs, Context &ctx)
static std::unique_ptr< rvsdg::BinaryOperation > ConvertIntegerBinaryOperation(const ::llvm::Instruction::BinaryOps binaryOperation, std::size_t numBits)
static const Variable * convert_constantVector(::llvm::Constant *c, std::vector< std::unique_ptr< llvm::ThreeAddressCode >> &tacs, Context &ctx)
static EnumAttribute ConvertEnumAttribute(const ::llvm::Attribute &attribute)
static const llvm::Linkage & convert_linkage(const ::llvm::GlobalValue::LinkageTypes &linkage)
std::unique_ptr< InterProceduralGraphModule > ConvertLlvmModule(::llvm::Module &llvmModule)
static bool isMallocCall(const ::llvm::CallInst &callInstruction)
static const Variable * ConvertBranchInstruction(::llvm::Instruction *instruction, tacsvector_t &tacs, Context &ctx)
jlm::llvm::CallingConvention convertCallingConventionToJlm(::llvm::CallingConv::ID cc)
static const Variable * convert_alloca_instruction(::llvm::Instruction *instruction, tacsvector_t &tacs, Context &ctx)
static const Variable * convert_constantArray(::llvm::Constant *c, std::vector< std::unique_ptr< llvm::ThreeAddressCode >> &tacs, Context &ctx)
const Variable * ConvertValueOrFunction(::llvm::Value *v, tacsvector_t &tacs, Context &ctx)
static const Variable * convert(const ::llvm::ICmpInst *instruction, tacsvector_t &tacs, Context &ctx)
static std::unique_ptr< rvsdg::BinaryOperation > ConvertPointerIcmpPredicate(const ::llvm::CmpInst::Predicate predicate)
@ availableExternallyLinkage
static const Variable * convert_int_constant(::llvm::Constant *c, std::vector< std::unique_ptr< ThreeAddressCode >> &tacs, Context &)
static const Variable * ConvertPhiInstruction(::llvm::Instruction *i, tacsvector_t &tacs, Context &ctx)
static void PatchPhiOperands(const std::vector<::llvm::PHINode * > &phis, Context &ctx)
static const Variable * convert_constantPointerNull(::llvm::Constant *constant, std::vector< std::unique_ptr< llvm::ThreeAddressCode >> &tacs, Context &ctx)
static const Variable * convertFMulAddIntrinsic(const ::llvm::CallInst &instruction, 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_store_instruction(::llvm::Instruction *i, tacsvector_t &tacs, Context &ctx)
static const Variable * convert_cast_instruction(::llvm::Instruction *i, tacsvector_t &tacs, Context &ctx)
static const Variable * createCall(const ::llvm::CallInst &callInstruction, tacsvector_t &threeAddressCodes, Context &context)
static const Variable * convertMemCpyCall(const ::llvm::IntrinsicInst *instruction, tacsvector_t &threeAddressCodes, Context &context)
static AttributeSet convert_attributes(const ::llvm::AttributeSet &as, TypeConverter &typeConverter)
static const Variable * convertInsertValueInstruction(const ::llvm::InsertValueInst &instruction, tacsvector_t &tacs, Context &context)
static std::unique_ptr< ControlFlowGraph > create_cfg(::llvm::Function &f, Context &ctx)
static const Variable * convert_blockAddress(::llvm::Constant *constant, std::vector< std::unique_ptr< llvm::ThreeAddressCode >> &, Context &)
static const Variable * convert_undefvalue(::llvm::Constant *c, std::vector< std::unique_ptr< llvm::ThreeAddressCode >> &tacs, Context &ctx)
static const Variable * convert_load_instruction(::llvm::Instruction *i, tacsvector_t &tacs, Context &ctx)
static void declare_globals(::llvm::Module &lm, Context &ctx)
static StringAttribute ConvertStringAttribute(const ::llvm::Attribute &attribute)
static void convert_global_value(::llvm::GlobalVariable &gv, Context &ctx)
static const Variable * convertFreezeInstruction(::llvm::Instruction *i, tacsvector_t &tacs, Context &ctx)
static const Variable * convert_constantDataVector(::llvm::Constant *constant, std::vector< std::unique_ptr< llvm::ThreeAddressCode >> &tacs, Context &ctx)
static const Variable * convert_unreachable_instruction(::llvm::Instruction *i, tacsvector_t &, Context &ctx)
static const Variable * convert_getelementptr_instruction(::llvm::Instruction *inst, tacsvector_t &tacs, Context &ctx)
void straighten(ControlFlowGraph &cfg)
static const Variable * convertIntrinsicInstruction(const ::llvm::IntrinsicInst &intrinsicInstruction, tacsvector_t &threeAddressCodes, Context &context)
static const Variable * convertSwitchInstruction(::llvm::SwitchInst *switchInstruction, tacsvector_t &tacs, Context &ctx)
static std::vector<::llvm::PHINode * > convert_instructions(::llvm::Function &function, Context &ctx)
static bool IsVolatile(const ::llvm::Value &value)
static const Variable * convert_return_instruction(::llvm::Instruction *instruction, tacsvector_t &tacs, Context &ctx)
static const Variable * ConvertConstantStruct(::llvm::Constant *c, std::vector< std::unique_ptr< llvm::ThreeAddressCode >> &tacs, Context &ctx)
static bool isFreeCall(const ::llvm::CallInst &callInstruction)
static const Variable * convertCallInstruction(const ::llvm::CallInst &callInstruction, tacsvector_t &threeAddressCodes, Context &context)
static std::unique_ptr< llvm::Argument > convert_argument(const ::llvm::Argument &argument, Context &ctx)
static const Variable * convert_constantDataArray(::llvm::Constant *constant, std::vector< std::unique_ptr< llvm::ThreeAddressCode >> &tacs, Context &ctx)
static void EnsureSingleInEdgeToExitNode(ControlFlowGraph &cfg)
static const Variable * convert_function(::llvm::Constant *c, tacsvector_t &tacs, Context &ctx)
Attribute::kind ConvertAttributeKind(const ::llvm::Attribute::AttrKind &kind)
static const Variable * convert_select_instruction(::llvm::Instruction *i, tacsvector_t &tacs, Context &ctx)
util::BijectiveMap< const ::llvm::BasicBlock *, BasicBlock * > BasicBlockMap
AttributeList convertAttributeList(const ::llvm::AttributeList &attributeList, const size_t numParameters, TypeConverter &typeConverter)
static const Variable * convertFreeCall(const ::llvm::CallInst &instruction, tacsvector_t &threeAddressCodes, Context &context)
static std::unique_ptr< rvsdg::BinaryOperation > ConvertIntegerIcmpPredicate(const ::llvm::CmpInst::Predicate predicate, const std::size_t numBits)
static const Variable * ConvertConstant(::llvm::Constant *, std::vector< std::unique_ptr< llvm::ThreeAddressCode >> &, Context &)
const Variable * ConvertValue(::llvm::Value *v, tacsvector_t &tacs, Context &ctx)
void prune(ControlFlowGraph &cfg)
static std::vector< jlm::rvsdg::Output * > operands(const Node *node)
static std::string strfmt(Args... args)