13 #include <llvm/ADT/PostOrderIterator.h>
14 #include <llvm/IR/BasicBlock.h>
15 #include <llvm/IR/Function.h>
16 #include <llvm/IR/Instructions.h>
17 #include <llvm/IR/Module.h>
22 static std::vector<::llvm::PHINode *>
25 std::vector<::llvm::PHINode *> phis;
26 ::llvm::ReversePostOrderTraversal<::llvm::Function *> rpotraverser(&
function);
27 for (
auto & bb : rpotraverser)
29 for (
auto & instruction : *bb)
39 if (!tacs.empty() && is<SsaPhiOperation>(tacs.back()->operation()))
41 auto phi = ::llvm::dyn_cast<::llvm::PHINode>(&instruction);
60 for (
const auto & phi : phis)
62 std::vector<ControlFlowGraphNode *> incomingNodes;
63 std::vector<const Variable *>
operands;
64 for (
size_t n = 0; n < phi->getNumOperands(); n++)
69 if (!ctx.
has(phi->getIncomingBlock(n)))
75 auto predecessor = ctx.
get(phi->getIncomingBlock(n));
76 if (std::find(incomingNodes.begin(), incomingNodes.end(), predecessor) != incomingNodes.end())
82 predecessor->insert_before_branch(tacs);
83 incomingNodes.push_back(predecessor);
88 auto phi_tac = util::assertedCast<const ThreeAddressCodeVariable>(ctx.
lookup_value(phi))->tac();
99 ::llvm::ReversePostOrderTraversal<::llvm::Function *> rpotraverser(&f);
100 for (
auto & bb : rpotraverser)
109 typedef ::llvm::Attribute::AttrKind ak;
111 static std::unordered_map<::llvm::Attribute::AttrKind, Attribute::kind> map(
226 return { kind, attribute.getValueAsInt() };
234 if (attribute.getKindAsEnum() == ::llvm::Attribute::AttrKind::ByVal)
240 if (attribute.getKindAsEnum() == ::llvm::Attribute::AttrKind::StructRet)
249 static StringAttribute
253 return { attribute.getKindAsString().str(), attribute.getValueAsString().str() };
260 for (
auto & attribute : as)
262 if (attribute.isEnumAttribute())
266 else if (attribute.isIntAttribute())
270 else if (attribute.isTypeAttribute())
274 else if (attribute.isStringAttribute())
287 static std::unique_ptr<llvm::Argument>
290 auto function = argument.getParent();
291 auto name = argument.getName().str();
294 convert_attributes(function->getAttributes().getParamAttrs(argument.getArgNo()), ctx);
302 auto exitNode = cfg.
exit();
304 if (exitNode->NumInEdges() == 0)
326 auto stronglyConnectedComponents =
find_sccs(cfg);
327 for (
auto stronglyConnectedComponent : stronglyConnectedComponents)
331 if (sccStructure->NumExitEdges() == 0)
333 auto repetitionEdge = *sccStructure->RepetitionEdges().begin();
337 auto op = std::make_unique<rvsdg::ControlConstantOperation>(
343 basicBlock->add_outedge(exitNode);
344 basicBlock->add_outedge(repetitionEdge->sink());
346 repetitionEdge->divert(basicBlock);
352 if (exitNode->NumInEdges() == 1)
360 exitNode->divert_inedges(basicBlock);
361 basicBlock->add_outedge(exitNode);
364 static std::unique_ptr<ControlFlowGraph>
374 for (
const auto & arg : f.args())
383 JLM_ASSERT(n < node->fcttype().NumArguments());
384 auto &
type = node->fcttype().Arguments()[n++];
387 JLM_ASSERT(n < node->fcttype().NumArguments());
389 auto & iotype = node->fcttype().Arguments()[n++];
390 auto iostate = cfg.entry()->append_argument(
Argument::create(
"_io_", iotype));
392 auto & memtype = node->fcttype().Arguments()[n++];
393 auto memstate = cfg.entry()->append_argument(
Argument::create(
"_s_", memtype));
395 JLM_ASSERT(n == node->fcttype().NumArguments());
402 add_arguments(f, *cfg, ctx);
407 cfg->exit()->divert_inedges(entry_block);
408 entry_block->add_outedge(bbmap.LookupKey(&f.getEntryBlock()));
412 if (!f.getReturnType()->isVoidTy())
416 result = entry_block->last()->result(0);
418 JLM_ASSERT(node->fcttype().NumResults() == 3);
420 cfg->exit()->append_result(result);
422 cfg->exit()->append_result(ctx.
iostate());
443 if (
function.isDeclaration())
449 fv->function()->add_cfg(
create_cfg(
function, ctx));
456 static std::unordered_map<::llvm::GlobalValue::LinkageTypes, llvm::Linkage> map(
458 { ::llvm::GlobalValue::AvailableExternallyLinkage,
477 auto create_data_node = [](const ::llvm::GlobalVariable & gv,
Context & ctx)
479 auto name = gv.getName().str();
480 auto constant = gv.isConstant();
483 auto section = gv.getSection().str();
494 auto create_function_node = [](const ::llvm::Function & f,
Context & ctx)
496 auto name = f.getName().str();
504 for (
auto & gv : lm.globals())
506 auto node = create_data_node(gv, ctx);
510 for (
auto & f : lm.getFunctionList())
512 auto node = create_function_node(f, ctx);
517 static std::unique_ptr<DataNodeInit>
520 if (!gv.hasInitializer())
523 auto init = gv.getInitializer();
526 return std::make_unique<DataNodeInit>(ctx.
lookup_value(init));
528 return std::make_unique<DataNodeInit>(std::move(tacs));
544 for (
auto & gv : lm.globals())
547 for (
auto & f : lm.getFunctionList())
551 std::unique_ptr<InterProceduralGraphModule>
556 llvmModule.getTargetTriple(),
557 llvmModule.getDataLayoutStr());
static std::unique_ptr< Argument > create(const std::string &name, std::shared_ptr< const jlm::rvsdg::Type > type, const AttributeSet &attributes)
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)
const llvm::Variable * lookup_value(const ::llvm::Value *value) const noexcept
llvm::Variable * memory_state() const noexcept
llvm::Variable * iostate() const noexcept
void set_memory_state(llvm::Variable *state)
InterProceduralGraphModule & module() const noexcept
void set_iostate(llvm::Variable *state)
void set_result(const llvm::Variable *result)
void set_basic_block_map(BasicBlockMap bbmap)
BasicBlock * get(const ::llvm::BasicBlock *bb) const noexcept
void set_node(InterProceduralGraphNode *node) noexcept
void insert_value(const ::llvm::Value *value, const llvm::Variable *variable)
TypeConverter & GetTypeConverter() noexcept
bool has(const ::llvm::BasicBlock *bb) const noexcept
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, bool constant)
static FunctionNode * create(InterProceduralGraph &ipg, const std::string &name, std::shared_ptr< const rvsdg::FunctionType > type, const llvm::Linkage &linkage, const AttributeSet &attributes)
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
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::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
bool Insert(const K &key, const V &value)
#define JLM_UNREACHABLE(msg)
Global memory state passed between functions.
static void convert_globals(::llvm::Module &lm, Context &ctx)
std::vector< StronglyConnectedComponent > find_sccs(const ControlFlowGraph &cfg)
static IntAttribute ConvertIntAttribute(const ::llvm::Attribute &attribute)
std::vector< std::unique_ptr< llvm::ThreeAddressCode > > tacsvector_t
static AttributeSet convert_attributes(const ::llvm::AttributeSet &as, Context &ctx)
static BasicBlockMap convert_basic_blocks(::llvm::Function &f, ControlFlowGraph &cfg)
static TypeAttribute ConvertTypeAttribute(const ::llvm::Attribute &attribute, Context &ctx)
static std::unique_ptr< DataNodeInit > create_initialization(::llvm::GlobalVariable &gv, Context &ctx)
static EnumAttribute ConvertEnumAttribute(const ::llvm::Attribute &attribute)
static const llvm::Linkage & convert_linkage(const ::llvm::GlobalValue::LinkageTypes &linkage)
const Variable * ConvertConstant(::llvm::Constant *, std::vector< std::unique_ptr< llvm::ThreeAddressCode >> &, Context &)
std::unique_ptr< InterProceduralGraphModule > ConvertLlvmModule(::llvm::Module &llvmModule)
@ availableExternallyLinkage
static void PatchPhiOperands(const std::vector<::llvm::PHINode * > &phis, Context &ctx)
const Variable * ConvertValue(::llvm::Value *v, tacsvector_t &tacs, Context &ctx)
static std::unique_ptr< ControlFlowGraph > create_cfg(::llvm::Function &f, 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)
void straighten(ControlFlowGraph &cfg)
static std::vector<::llvm::PHINode * > convert_instructions(::llvm::Function &function, Context &ctx)
static std::unique_ptr< llvm::Argument > convert_argument(const ::llvm::Argument &argument, Context &ctx)
const Variable * ConvertInstruction(::llvm::Instruction *i, 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)
util::BijectiveMap< const ::llvm::BasicBlock *, BasicBlock * > BasicBlockMap
void prune(ControlFlowGraph &cfg)
static std::string type(const Node *n)
static std::vector< jlm::rvsdg::Output * > operands(const Node *node)