29 Func->setDefined(
true);
31 bool IsEligibleForCompilation =
Func->isLambdaStaticInvoker() ||
33 FuncDecl->
hasAttr<MSConstexprAttr>();
35 if (!IsEligibleForCompilation) {
36 Func->setIsFullyCompiled(
true);
41 if (
Func->isLambdaCallOperator()) {
44 const Record *R = P.getOrCreateRecord(ParentDecl);
46 llvm::DenseMap<const ValueDecl *, FieldDecl *> LC;
51 for (
const auto &Cap : LC) {
52 unsigned Offset = R->getField(Cap.second)->Offset;
54 Offset, Cap.second->getType()->isReferenceType()};
57 QualType CaptureType = R->getField(LTC)->Decl->getType();
65 for (
unsigned ParamIndex = 0, N =
Func->getNumWrittenParams();
66 ParamIndex != N; ++ParamIndex) {
70 this->
Params.insert({PD, {ParamIndex, Ctx.canClassify(PD->
getType())}});
75 Func->setIsFullyCompiled(
true);
82 Scopes.emplace_back(std::move(DS));
86 Func->setCode(FuncDecl, NextLocalOffset, std::move(Code), std::move(SrcMap),
87 std::move(Scopes), FuncDecl->
hasBody(), IsValid);
88 Func->setIsFullyCompiled(
true);
92 NextLocalOffset +=
sizeof(
Block);
93 unsigned Location = NextLocalOffset;
99 const size_t Target = Code.size();
100 LabelOffsets.insert({Label,
Target});
102 if (
auto It = LabelRelocs.find(Label); It != LabelRelocs.end()) {
103 for (
unsigned Reloc : It->second) {
104 using namespace llvm::support;
107 void *Location = Code.data() + Reloc -
align(
sizeof(int32_t));
109 const int32_t Offset =
Target -
static_cast<int64_t
>(Reloc);
110 endian::write<int32_t, llvm::endianness::native>(Location, Offset);
112 LabelRelocs.erase(It);
116int32_t ByteCodeEmitter::getOffset(LabelTy Label) {
118 const int64_t Position =
123 if (
auto It = LabelOffsets.find(Label); It != LabelOffsets.end())
124 return It->second - Position;
127 LabelRelocs[Label].push_back(Position);
134 size_t ValPos = Code.size();
137 if constexpr (std::is_pointer_v<T>)
142 if (ValPos + Size > std::numeric_limits<unsigned>::max())
147 assert(
aligned(ValPos + Size));
148 Code.resize_for_overwrite(ValPos + Size);
150 if constexpr (std::is_pointer_v<T>)
153 new (Code.data() + ValPos)
T(Val);
162 size_t ValPos = Code.size();
163 size_t Size =
align(Val.bytesToSerialize());
165 if (ValPos + Size > std::numeric_limits<unsigned>::max())
170 assert(
aligned(ValPos + Size));
171 Code.resize_for_overwrite(ValPos + Size);
173 Val.serialize(Code.data() + ValPos);
198template <
typename... Tys>
205 if (SrcMap.empty() || SrcMap.back() != SI)
206 SrcMap.push(Code.size(), SI);
208 return (
emit(Code, Args) && ...);
212 return emitJt(getOffset(Label), SI);
216 return emitJf(getOffset(Label), SI);
220 return emitJmp(getOffset(Label), SI);
231 if (!this->emitBCP(getOffset(EndLabel),
T, E))
233 if (!this->
visit(Arg))
243#include "Opcodes.inc"
This file provides some common utility functions for processing Lambda related AST Constructs.
static bool emit(llvm::SmallVectorImpl< std::byte > &Code, const T &Val)
Helper to write bytecode and bail out if 32-bit offsets become invalid.
static bool emitSerialized(llvm::SmallVectorImpl< std::byte > &Code, const T &Val)
Emits a serializable value.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Represents a C++ struct/union/class.
void getCaptureFields(llvm::DenseMap< const ValueDecl *, FieldDecl * > &Captures, FieldDecl *&ThisCapture) const
For a closure type, retrieve the mapping from captured variables and this to the non-static data memb...
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
bool isInvalidDecl() const
This represents one expression.
Represents a member of a struct/union/class.
Represents a function declaration or definition.
const ParmVarDecl * getParamDecl(unsigned i) const
bool isThisDeclarationADefinition() const
Returns whether this specific declaration of the function is also a definition that does not contain ...
bool isConstexpr() const
Whether this is a (C++11) constexpr function or constexpr constructor.
bool hasBody(const FunctionDecl *&Definition) const
Returns true if the function has a body.
Represents a parameter to a function.
A (possibly-)qualified type.
bool isPointerOrReferenceType() const
A memory block, either on the stack or in the heap.
static constexpr uint8_t InlineDescMD
bool jump(const LabelTy &Label, SourceInfo SI)
void emitLabel(LabelTy Label)
Define a label.
Local createLocal(const Descriptor *D)
Callback for local registration.
ParamOffset LambdaThisCapture
Offset of the This parameter in a lambda record.
llvm::DenseMap< const ValueDecl *, ParamOffset > LambdaCaptures
Lambda captures.
bool jumpTrue(const LabelTy &Label, SourceInfo SI)
Emits jumps.
bool speculate(const CallExpr *E, const LabelTy &EndLabel)
Speculative execution.
bool fallthrough(const LabelTy &Label)
bool jumpFalse(const LabelTy &Label, SourceInfo SI)
virtual bool visitFunc(const FunctionDecl *E)=0
Methods implemented by the compiler.
std::optional< SourceInfo > LocOverride
llvm::DenseMap< const ParmVarDecl *, FuncParam > Params
Parameter indices.
virtual bool visit(const Expr *E)=0
void compileFunc(const FunctionDecl *FuncDecl, Function *Func)
Compiles the function into the module.
llvm::SmallVector< SmallVector< Local, 8 >, 2 > Descriptors
Local descriptors.
Wrapper around fixed point types.
If a Floating is constructed from Memory, it DOES NOT OWN THAT MEMORY.
If an IntegralAP is constructed from Memory, it DOES NOT OWN THAT MEMORY.
Structure/Class descriptor.
Describes the statement/declaration an opcode was generated from.
constexpr bool aligned(uintptr_t Value)
constexpr size_t align(size_t Size)
Aligns a size to the pointer alignment.
PrimType
Enumeration of the primitive types of the VM.
Top level wrappers for InstallAPI frontend operations.
const FunctionProtoType * T
__UINTPTR_TYPE__ uintptr_t
An unsigned integer type with the property that any valid pointer to void can be converted to this ty...
Describes a memory block created by an allocation site.
unsigned getAllocSize() const
Returns the allocated size, including metadata.
Information about a local's storage.