MimIR
MimIR is my Intermediate Representation
Loading...
Searching...
No Matches
mim::plug::ll::Emitter Class Reference

#include <mim/plug/ll/ll.h>

Inheritance diagram for mim::plug::ll::Emitter:
[legend]

Public Types

enum class  Rt {
  embed ,
  ext
}
 How the C runtime wrappers (compiled to a <name>.ll via add_mim_runtime) reach the output. More...
using Super = NestPhase<Lam>

Public Member Functions

 Emitter (World &world, std::string name, std::ostream &ostream)
void start () override
 Actual entry.
void visit (const Nest &) override
void emit_imported (Lam *)
virtual std::string prepare ()
virtual void emit_epilogue (Lam *lam)
void finalize ()
std::string emit_bb (BB &bb, const Def *def)
virtual std::optional< std::string > isa_targetspecific_intrinsic (BB &, const Def *)
template<class... Args>
void declare (std::format_string< Args... > s, Args &&... args)
void rt_mode (Rt rt)
bool load_rt_module (std::string_view filename)
 Locates the runtime module rt/<filename> (produced by add_mim_runtime) in the driver's search paths, reads it, and stores it for Rt::embed splicing.
template<class... Args>
void declare_rt (std::format_string< Args... > sig, Args &&... args)
 Declares a runtime wrapper sig (implemented in a C runtime, see add_mim_runtime) and records that the runtime is required by this module.
Public Member Functions inherited from mim::NestPhase< Lam >
 NestPhase (World &world, std::string name, bool elide_empty, bool schedule=false)
 NestPhase (World &world, flags_t annex, bool elide_empty, bool schedule=false)
const Nest & nest () const
Public Member Functions inherited from mim::ClosedMutPhase< M >
 ClosedMutPhase (World &world, std::string name, bool elide_empty, bool schedule=false)
 ClosedMutPhase (World &world, flags_t annex, bool elide_empty, bool schedule=false)
bool elide_empty () const
bool schedule () const
Public Member Functions inherited from mim::Phase
 Phase (World &world, std::string name)
 Phase (World &world, flags_t annex)
virtual ~Phase ()=default
virtual std::unique_ptr< Phase > recreate ()
 Creates a new instance; needed by a fixed-point PhaseMan.
virtual void apply (const App *)
 Invoked if your Phase has additional args.
virtual void apply (Phase &)
 Dito, but invoked by Phase::recreate.
virtual bool redirects () const
 If true, Phase::create uses take_resolved().
virtual std::unique_ptr< Phase > take_resolved ()
 The Phase to use instead; nullptr means elide.
World & world ()
Driver & driver ()
const fe::Log & log () const
std::string_view name () const
flags_t annex () const
const fe::Vector< std::string > & args ()
 Command-line arguments passed to this Phase's plugin via -X <plugin>:<arg>.
bool todo () const
void invalidate (bool todo=true)
 Signals that another round of fixed-point iteration is required, either as part of.
virtual void run ()
 Entry point and generates some debug output; invokes Phase::start.
void profile_count (std::string_view key, uint64_t n=1)
 Adds n to the custom fe::Profiler counter key of the current run; no-op unless profiling is enabled.

Public Attributes

fe::Tab tab = fe::Tab::spaces()

Protected Member Functions

std::ostream & ostream () const
std::string emit (const Def *def)
 Recursively emits code.
std::string emit_unsafe (const Def *def)
 As above but yielding an empty string is permitted.
const Scheduler::Schedule & schedule () const
 The Scheduler::schedule of the function currently being emitted; see Emitter::visit.
std::string id (const Def *, bool force_bb=false) const
virtual std::string convert (const Def *type, bool simd=true)
 Converts type to its LLVM representation as a value (simd) or in memory (!simd).
std::string convert_ret_pi (const Pi *)
std::optional< std::pair< nat_t, const Def * > > vectorize (const Def *type) const
 Lane count and element type if a value of type is an LLVM vector.
bool has_vec (const Def *type) const
 Whether type's value representation contains an LLVM vector and hence differs from its memory one.
void emit_phi (Lam *callee, const Def *phi, std::string arg, Lam *pred)
 Registers arg as an incoming phi value for phi in callee, coming from predecessor pred.
void emit_phi_args (Lam *callee, const App *app, Lam *pred)
 Wires all non-mem.M arguments of app into callee's phis, coming from predecessor pred.
virtual std::string emit_slot (BB &bb, const App *app, const Def *pointee, const Def *)
 Emits the storage backing a mem.slot of type pointee and yields the pointer value.
Protected Member Functions inherited from mim::ClosedMutPhase< M >
virtual void visit (M *)=0
M * root () const

Protected Attributes

Lam * curr_lam_ = nullptr
std::ostream & ostream_
Scheduler scheduler_
Scheduler::Schedule schedule_
DefMap< std::string > locals_
std::array< DefMap< std::string >, 2 > types_
 Indexed by the simd flag of Emitter::convert.
LamMap< BB > lam2bb_
std::set< std::string > decls_
std::ostringstream type_decls_
std::ostringstream vars_decls_
std::ostringstream func_decls_
std::ostringstream func_impls_
LamMap< const Def * > simd_phi_
LamMap< std::pair< u64, bool > > loop_md_
bool simd_ = true
Rt rt_ = Rt::embed
bool rt_used_ = false
std::string rt_module_
Protected Attributes inherited from mim::Phase
std::string name_

Static Protected Attributes

static constexpr u64 LoopMdBase = 1000
 Loop-metadata node id per ll.vec/ll.novec-annotated loop header, and whether it may vectorize; LoopMdBase and LoopMdBase + 1 hold the shared enable/disable hints, the per-loop nodes follow, clear of the ids the embedded runtime module brings along.

Friends

void mim_ll_convert (Emitter &e, const Def *type, bool simd, std::string &res)
 The heavy, target-independent emitter methods are compiled once into libmim_ll (see ll.cpp).
void mim_ll_finalize (Emitter &e)
void mim_ll_emit_epilogue (Emitter &e, Lam *lam)
void mim_ll_emit_bb (Emitter &e, BB &bb, const Def *def, std::string &res)

Additional Inherited Members

Static Public Member Functions inherited from mim::Phase
static std::unique_ptr< Phase > create (const Flags2Phases &phases, const Def *def)
template<class A, class P>
static void hook (Flags2Phases &phases)
template<class P, class... Args>
static void run (Args &&... args)
 Runs a single Phase.

Detailed Description

Definition at line 126 of file ll.h.

Member Typedef Documentation

◆ Super

Definition at line 128 of file ll.h.

Member Enumeration Documentation

◆ Rt

enum class mim::plug::ll::Emitter::Rt
strong

How the C runtime wrappers (compiled to a <name>.ll via add_mim_runtime) reach the output.

Enumerator
embed 

Splice the wrapper IR into the emitted module so it is self-contained.

ext 

Only declare the wrappers; the runtime is linked in externally.

Definition at line 167 of file ll.h.

Constructor & Destructor Documentation

◆ Emitter()

Member Function Documentation

◆ convert()

virtual std::string mim::plug::ll::Emitter::convert ( const Def * type,
bool simd = true )
inlineprotectedvirtual

Converts type to its LLVM representation as a value (simd) or in memory (!simd).

Only values use LLVM vectors; memory keeps the plain array layout C expects.

Reimplemented in mim::plug::nvptx::HostEmitter.

Definition at line 220 of file ll.h.

Referenced by mim::plug::nvptx::HostEmitter::convert(), convert_ret_pi(), emit_imported(), emit_slot(), mim::plug::nvptx::DeviceEmitter::emit_slot(), mim::plug::nvptx::DeviceEmitter::isa_targetspecific_intrinsic(), prepare(), and mim::plug::nvptx::DeviceEmitter::prepare().

◆ convert_ret_pi()

std::string mim::plug::ll::Emitter::convert_ret_pi ( const Pi * pi)
inlineprotected

◆ declare()

template<class... Args>
void mim::plug::ll::Emitter::declare ( std::format_string< Args... > s,
Args &&... args )
inline

◆ declare_rt()

template<class... Args>
void mim::plug::ll::Emitter::declare_rt ( std::format_string< Args... > sig,
Args &&... args )
inline

Declares a runtime wrapper sig (implemented in a C runtime, see add_mim_runtime) and records that the runtime is required by this module.

In Rt::ext mode the declaration is emitted like any other declare. In Rt::embed mode the wrapper's definition is spliced into the output, so emitting a declare as well would be a redefinition — hence it is suppressed here.

Definition at line 187 of file ll.h.

References mim::Phase::args(), declare(), ext, rt_, and rt_used_.

◆ emit()

std::string mim::plug::ll::Emitter::emit ( const Def * def)
inlineprotected

Recursively emits code.

mem-typed defs yield an empty string, which this variant asserts against.

Definition at line 197 of file ll.h.

References emit_unsafe().

Referenced by mim::plug::nvptx::DeviceEmitter::isa_targetspecific_intrinsic(), and mim::plug::nvptx::HostEmitter::isa_targetspecific_intrinsic().

◆ emit_bb()

std::string mim::plug::ll::Emitter::emit_bb ( BB & bb,
const Def * def )
inline

Definition at line 153 of file ll.h.

Referenced by emit_unsafe().

◆ emit_epilogue()

virtual void mim::plug::ll::Emitter::emit_epilogue ( Lam * lam)
inlinevirtual

Reimplemented in mim::plug::nvptx::HostEmitter.

Definition at line 151 of file ll.h.

Referenced by mim::plug::nvptx::HostEmitter::emit_epilogue(), and visit().

◆ emit_imported()

void mim::plug::ll::Emitter::emit_imported ( Lam * lam)
inline

Definition at line 499 of file ll.h.

References convert(), convert_ret_pi(), mim::Lam::doms(), func_decls_, mim::Axm::isa(), mim::Pi::ret_pi(), and mim::Lam::type().

Referenced by visit().

◆ emit_phi()

void mim::plug::ll::Emitter::emit_phi ( Lam * callee,
const Def * phi,
std::string arg,
Lam * pred )
inlineprotected

Registers arg as an incoming phi value for phi in callee, coming from predecessor pred.

Definition at line 233 of file ll.h.

References mim::Def::blame(), id(), lam2bb_, locals_, MIM_LL_BE, and mim::ClosedMutPhase< M >::root().

Referenced by emit_phi_args().

◆ emit_phi_args()

void mim::plug::ll::Emitter::emit_phi_args ( Lam * callee,
const App * app,
Lam * pred )
inlineprotected

Wires all non-mem.M arguments of app into callee's phis, coming from predecessor pred.

Definition at line 244 of file ll.h.

References mim::App::arg(), emit_phi(), emit_unsafe(), mim::Axm::isa(), mim::Def::num_tvars(), and mim::Def::var().

◆ emit_slot()

virtual std::string mim::plug::ll::Emitter::emit_slot ( BB & bb,
const App * app,
const Def * pointee,
const Def *  )
inlineprotectedvirtual

Emits the storage backing a mem.slot of type pointee and yields the pointer value.

The generic backend allocates on the stack; targets may override (e.g. a global in a specific address space). Kept inline on purpose so Emitter retains no vtable key function (else its vtable would live in a single module and break derived backends loaded from a separate plugin).

Reimplemented in mim::plug::nvptx::DeviceEmitter.

Definition at line 258 of file ll.h.

References mim::plug::ll::BB::body(), convert(), and mim::Def::unique_name().

◆ emit_unsafe()

std::string mim::plug::ll::Emitter::emit_unsafe ( const Def * def)
inlineprotected

◆ finalize()

void mim::plug::ll::Emitter::finalize ( )
inline

Definition at line 152 of file ll.h.

Referenced by visit().

◆ has_vec()

bool mim::plug::ll::Emitter::has_vec ( const Def * type) const
inlineprotected

Whether type's value representation contains an LLVM vector and hence differs from its memory one.

Definition at line 349 of file ll.h.

References has_vec(), mim::plug::ll::is_simd(), and simd_.

Referenced by has_vec().

◆ id()

◆ isa_targetspecific_intrinsic()

virtual std::optional< std::string > mim::plug::ll::Emitter::isa_targetspecific_intrinsic ( BB & ,
const Def *  )
inlinevirtual

Reimplemented in mim::plug::nvptx::DeviceEmitter, and mim::plug::nvptx::HostEmitter.

Definition at line 159 of file ll.h.

◆ load_rt_module()

bool mim::plug::ll::Emitter::load_rt_module ( std::string_view filename)
inline

Locates the runtime module rt/<filename> (produced by add_mim_runtime) in the driver's search paths, reads it, and stores it for Rt::embed splicing.

Backends share this instead of duplicating the lookup: ll loads ll_rt.ll, nvptx loads nvptx_rt.ll, and so on — one merged module per plugin.

Returns
whether the module was found.

Definition at line 485 of file ll.h.

References mim::Phase::driver(), mim::World::log(), rt_module_, and mim::Phase::world().

Referenced by mim::plug::nvptx::emit_host().

◆ ostream()

std::ostream & mim::plug::ll::Emitter::ostream ( ) const
inlineprotected

◆ prepare()

◆ rt_mode()

void mim::plug::ll::Emitter::rt_mode ( Rt rt)
inline

Definition at line 172 of file ll.h.

References rt_.

Referenced by mim::plug::nvptx::emit_host().

◆ schedule()

const Scheduler::Schedule & mim::plug::ll::Emitter::schedule ( ) const
inlineprotected

The Scheduler::schedule of the function currently being emitted; see Emitter::visit.

Definition at line 214 of file ll.h.

References schedule_.

◆ start()

void mim::plug::ll::Emitter::start ( )
inlineoverridevirtual

◆ vectorize()

std::optional< std::pair< nat_t, const Def * > > mim::plug::ll::Emitter::vectorize ( const Def * type) const
inlineprotected

Lane count and element type if a value of type is an LLVM vector.

Definition at line 345 of file ll.h.

References mim::plug::ll::is_simd(), and simd_.

◆ visit()

◆ mim_ll_convert

void mim_ll_convert ( Emitter & e,
const Def * type,
bool simd,
std::string & res )
friend

The heavy, target-independent emitter methods are compiled once into libmim_ll (see ll.cpp).

libmim_nvptx reaches them through these extern "C" shims instead of recompiling the bodies; Emitter caches the pointers via GET_FUN_PTR in its constructor.

Definition at line 1158 of file ll.cpp.

References Emitter(), MIM_EXPORT, and mim_ll_convert.

Referenced by Emitter(), and mim_ll_convert.

◆ mim_ll_emit_bb

void mim_ll_emit_bb ( Emitter & e,
BB & bb,
const Def * def,
std::string & res )
friend

Definition at line 1163 of file ll.cpp.

References Emitter(), MIM_EXPORT, and mim_ll_emit_bb.

Referenced by Emitter(), and mim_ll_emit_bb.

◆ mim_ll_emit_epilogue

void mim_ll_emit_epilogue ( Emitter & e,
Lam * lam )
friend

Definition at line 1162 of file ll.cpp.

References Emitter(), MIM_EXPORT, and mim_ll_emit_epilogue.

Referenced by Emitter(), and mim_ll_emit_epilogue.

◆ mim_ll_finalize

void mim_ll_finalize ( Emitter & e)
friend

Definition at line 1161 of file ll.cpp.

References Emitter(), MIM_EXPORT, and mim_ll_finalize.

Referenced by Emitter(), and mim_ll_finalize.

Member Data Documentation

◆ curr_lam_

Lam* mim::plug::ll::Emitter::curr_lam_ = nullptr
protected

Definition at line 264 of file ll.h.

Referenced by emit_unsafe(), and visit().

◆ decls_

std::set<std::string> mim::plug::ll::Emitter::decls_
protected

Definition at line 272 of file ll.h.

Referenced by declare(), and start().

◆ func_decls_

std::ostringstream mim::plug::ll::Emitter::func_decls_
protected

Definition at line 275 of file ll.h.

Referenced by emit_imported(), and start().

◆ func_impls_

std::ostringstream mim::plug::ll::Emitter::func_impls_
protected

Definition at line 276 of file ll.h.

Referenced by prepare(), mim::plug::nvptx::DeviceEmitter::prepare(), and start().

◆ lam2bb_

◆ locals_

DefMap<std::string> mim::plug::ll::Emitter::locals_
protected

Definition at line 268 of file ll.h.

Referenced by emit_phi(), emit_unsafe(), prepare(), mim::plug::nvptx::DeviceEmitter::prepare(), and visit().

◆ loop_md_

LamMap<std::pair<u64, bool> > mim::plug::ll::Emitter::loop_md_
protected

Definition at line 283 of file ll.h.

Referenced by start().

◆ LoopMdBase

u64 mim::plug::ll::Emitter::LoopMdBase = 1000
staticconstexprprotected

Loop-metadata node id per ll.vec/ll.novec-annotated loop header, and whether it may vectorize; LoopMdBase and LoopMdBase + 1 hold the shared enable/disable hints, the per-loop nodes follow, clear of the ids the embedded runtime module brings along.

Definition at line 282 of file ll.h.

Referenced by start().

◆ ostream_

std::ostream& mim::plug::ll::Emitter::ostream_
protected

Definition at line 265 of file ll.h.

Referenced by Emitter(), and ostream().

◆ rt_

Rt mim::plug::ll::Emitter::rt_ = Rt::embed
protected

Definition at line 286 of file ll.h.

Referenced by declare_rt(), rt_mode(), and start().

◆ rt_module_

std::string mim::plug::ll::Emitter::rt_module_
protected

Definition at line 288 of file ll.h.

Referenced by load_rt_module(), and start().

◆ rt_used_

bool mim::plug::ll::Emitter::rt_used_ = false
protected

Definition at line 287 of file ll.h.

Referenced by declare_rt(), and start().

◆ schedule_

Scheduler::Schedule mim::plug::ll::Emitter::schedule_
protected

Definition at line 267 of file ll.h.

Referenced by schedule(), and visit().

◆ scheduler_

Scheduler mim::plug::ll::Emitter::scheduler_
protected

Definition at line 266 of file ll.h.

Referenced by emit_unsafe(), and visit().

◆ simd_

bool mim::plug::ll::Emitter::simd_ = true
protected

Definition at line 285 of file ll.h.

Referenced by mim::plug::nvptx::DeviceEmitter::DeviceEmitter(), has_vec(), and vectorize().

◆ simd_phi_

LamMap<const Def*> mim::plug::ll::Emitter::simd_phi_
protected

Definition at line 277 of file ll.h.

◆ tab

fe::Tab mim::plug::ll::Emitter::tab = fe::Tab::spaces()

Definition at line 143 of file ll.h.

◆ type_decls_

std::ostringstream mim::plug::ll::Emitter::type_decls_
protected

Definition at line 273 of file ll.h.

Referenced by start().

◆ types_

std::array<DefMap<std::string>, 2> mim::plug::ll::Emitter::types_
protected

Indexed by the simd flag of Emitter::convert.

Definition at line 269 of file ll.h.

◆ vars_decls_

std::ostringstream mim::plug::ll::Emitter::vars_decls_
protected

The documentation for this class was generated from the following files: