1
0
mirror of https://github.com/exaloop/codon.git synced 2025-06-03 15:03:52 +08:00
codon/compiler/sir/util/irtools.h

207 lines
8.0 KiB
C
Raw Normal View History

2021-09-27 14:02:44 -04:00
#pragma once
#include "sir/sir.h"
namespace codon {
2021-09-27 14:02:44 -04:00
namespace ir {
namespace util {
/// Checks whether a function has a given attribute.
/// @param func the function
/// @param attribute the attribute name
/// @return true if the function has the given attribute
bool hasAttribute(const Func *func, const std::string &attribute);
/// Checks whether a function comes from the standard library, and
/// optionally a specific module therein.
/// @param func the function
/// @param submodule module name (e.g. "std::bio"), or empty if
/// no module check is required
/// @return true if the function is from the standard library in
/// the given module
bool isStdlibFunc(const Func *func, const std::string &submodule = "");
/// Calls a function.
/// @param func the function
/// @param args vector of call arguments
/// @return call instruction with the given function and arguments
CallInstr *call(Func *func, const std::vector<Value *> &args);
/// Checks if a value represents a call of a particular function.
/// @param value the value to check
/// @param name the function's (unmangled) name
/// @param inputs vector of input types
/// @param output output type, null for no check
/// @param method true to ensure this call is a method call
/// @return true if value is a call matching all parameters above
bool isCallOf(const Value *value, const std::string &name,
const std::vector<types::Type *> &inputs, types::Type *output = nullptr,
bool method = false);
/// Checks if a value represents a call of a particular function.
/// @param value the value to check
/// @param name the function's (unmangled) name
/// @param numArgs argument count, negative for no check
/// @param output output type, null for no check
/// @param method true to ensure this call is a method call
/// @return true if value is a call matching all parameters above
bool isCallOf(const Value *value, const std::string &name, int numArgs = -1,
types::Type *output = nullptr, bool method = false);
/// Checks if a value represents a call to a magic method.
/// Magic method names start and end in "__" (two underscores).
/// @param value the value to check
/// @return true if value is a magic method call
bool isMagicMethodCall(const Value *value);
/// Constructs a new tuple.
/// @param args vector of tuple contents
/// @param M the module; inferred from elements if null
/// @return value represents a tuple with the given contents
Value *makeTuple(const std::vector<Value *> &args, Module *M = nullptr);
/// Constructs and assigns a new variable.
/// @param x the value to assign to the new variable
/// @param flow series flow in which to assign the new variable
/// @param parent function to add the new variable to, or null for global variable
/// @param prepend true to insert assignment at start of block
/// @return value containing the new variable
VarValue *makeVar(Value *x, SeriesFlow *flow, BodiedFunc *parent, bool prepend = false);
/// Dynamically allocates memory for the given type with the given
/// number of elements.
/// @param type the type
/// @param count integer value representing the number of elements
/// @return value representing a pointer to the allocated memory
Value *alloc(types::Type *type, Value *count);
/// Dynamically allocates memory for the given type with the given
/// number of elements.
/// @param type the type
/// @param count the number of elements
/// @return value representing a pointer to the allocated memory
Value *alloc(types::Type *type, int64_t count);
/// Builds a new series flow with the given contents. Returns
/// null if no contents are provided.
/// @param args contents of the series flow
/// @return new series flow
template <typename... Args> SeriesFlow *series(Args... args) {
std::vector<Value *> vals = {args...};
if (vals.empty())
return nullptr;
auto *series = vals[0]->getModule()->Nr<SeriesFlow>();
for (auto *val : vals) {
series->push_back(val);
}
return series;
}
/// Checks whether the given value is a constant of the given
/// type. Note that standard "int" corresponds to the C type
/// "int64_t", which should be used here.
/// @param x the value to check
/// @return true if the value is constant
template <typename T> bool isConst(const Value *x) { return isA<TemplatedConst<T>>(x); }
/// Checks whether the given value is a constant of the given
/// type, and that is has a particular value. Note that standard
/// "int" corresponds to the C type "int64_t", which should be used here.
/// @param x the value to check
/// @param value constant value to compare to
/// @return true if the value is constant with the given value
template <typename T> bool isConst(const Value *x, const T &value) {
if (auto *c = cast<TemplatedConst<T>>(x)) {
return c->getVal() == value;
}
return false;
}
/// Returns the constant represented by a given value. Raises an assertion
/// error if the given value is not constant. Note that standard
/// "int" corresponds to the C type "int64_t", which should be used here.
/// @param x the (constant) value
/// @return the constant represented by the given value
template <typename T> T getConst(const Value *x) {
auto *c = cast<TemplatedConst<T>>(x);
seqassert(c, "{} is not a constant", *x);
return c->getVal();
}
/// Gets a variable from a value.
/// @param x the value
/// @return the variable represented by the given value, or null if none
Var *getVar(Value *x);
/// Gets a variable from a value.
/// @param x the value
/// @return the variable represented by the given value, or null if none
const Var *getVar(const Value *x);
/// Gets a function from a value.
/// @param x the value
/// @return the function represented by the given value, or null if none
Func *getFunc(Value *x);
/// Gets a function from a value.
/// @param x the value
/// @return the function represented by the given value, or null if none
const Func *getFunc(const Value *x);
/// Loads value from a pointer.
/// @param ptr the pointer
/// @return the value pointed to by the argument
Value *ptrLoad(Value *ptr);
/// Stores a value into a pointer.
/// @param ptr the pointer
/// @param val the value to store
/// @return "__setitem__" call representing the store
Value *ptrStore(Value *ptr, Value *val);
/// Gets value from a tuple at the given index.
/// @param tuple the tuple
/// @param index the 0-based index
/// @return tuple element at the given index
Value *tupleGet(Value *tuple, unsigned index);
/// Stores value in a tuple at the given index. Since tuples are immutable,
/// a new instance is returned with the appropriate element replaced.
/// @param tuple the tuple
/// @param index the 0-based index
/// @param val the value to store
/// @return new tuple instance with the given value inserted
Value *tupleStore(Value *tuple, unsigned index, Value *val);
/// Gets a bodied standard library function from a value.
/// @param x the value
/// @param name name of the function
/// @param submodule optional module to check
/// @return the standard library function (with the given name, from the given
/// submodule) represented by the given value, or null if none
BodiedFunc *getStdlibFunc(Value *x, const std::string &name,
const std::string &submodule = "");
/// Gets a bodied standard library function from a value.
/// @param x the value
/// @param name name of the function
/// @param submodule optional module to check
/// @return the standard library function (with the given name, from the given
/// submodule) represented by the given value, or null if none
const BodiedFunc *getStdlibFunc(const Value *x, const std::string &name,
const std::string &submodule = "");
/// Gets the return type of a function.
/// @param func the function
/// @return the return type of the given function
types::Type *getReturnType(const Func *func);
/// Sets the return type of a function. Argument types remain unchanged.
/// @param func the function
/// @param rType the new return type
void setReturnType(Func *func, types::Type *rType);
} // namespace util
} // namespace ir
} // namespace codon