зеркало из https://github.com/dotnet/llilc.git
Merge pull request #482 from russellhadley/SplitOptionsClass
Add Reader required options
This commit is contained in:
Коммит
ef5ebebd32
|
@ -96,7 +96,7 @@ public:
|
|||
|
||||
/// \name Per invocation JIT Options
|
||||
//@{
|
||||
::Options Options;
|
||||
::Options *Options;
|
||||
//@}
|
||||
|
||||
/// \name Jit output sizes
|
||||
|
@ -239,11 +239,6 @@ public:
|
|||
/// A pointer to the singleton jit instance.
|
||||
static LLILCJit *TheJit;
|
||||
|
||||
/// \name CoreCLR GC information
|
||||
//@{
|
||||
bool ShouldInsertStatepoints; ///< Whether to insert gc.statepoint intrinsics
|
||||
//@}
|
||||
|
||||
private:
|
||||
/// Thread local storage for the jit's per-thread state.
|
||||
llvm::sys::ThreadLocal<LLILCJitPerThreadState> State;
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
//===----------------- include/Jit/options.h -------------------*- C++ -*-===//
|
||||
//
|
||||
// LLILC
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
// See LICENSE file in the project root for full license information.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file
|
||||
/// \brief Declaration of the Options class that encapsulates JIT options
|
||||
/// extracted from CoreCLR config values.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef JITOPTIONS_H
|
||||
#define JITOPTIONS_H
|
||||
|
||||
#include "options.h"
|
||||
|
||||
/// \brief The JIT options implementation.
|
||||
///
|
||||
/// This class queries the CoreCLR interface to compute the Options flags
|
||||
/// consumed by the JIT. The query logic here should only be usable from the
|
||||
/// base JIT at initialization time of the context.
|
||||
///
|
||||
/// This derived class is responsible for filling out the base fields
|
||||
/// as well as it's own. The base Options class contains options used in
|
||||
/// all configurations but includes to query logic to fill them out as that
|
||||
/// will be client based (JIT or AOT)
|
||||
///
|
||||
class JitOptions : public Options {
|
||||
public:
|
||||
/// Construct an JitOptions object based on the passed JitContext.
|
||||
JitOptions(LLILCJitContext &JitContext);
|
||||
|
||||
/// Destruct Options object.
|
||||
~JitOptions();
|
||||
|
||||
private:
|
||||
/// Set current JIT invocation as "AltJit". This sets up
|
||||
/// the JIT to filter based on the AltJit flag contents.
|
||||
/// \returns true if runing as the alternate JIT
|
||||
static bool queryIsAltJit(LLILCJitContext &JitContext);
|
||||
|
||||
/// \brief Compute dump level for the JIT
|
||||
///
|
||||
/// Dump level requested via CLR config for the JIT
|
||||
/// \returns Computed DumpLevel
|
||||
static ::DumpLevel queryDumpLevel(LLILCJitContext &JitContext);
|
||||
|
||||
/// \brief Set optimization level for the JIT.
|
||||
///
|
||||
/// Opt Level based on CLR provided flags and environment.
|
||||
/// \returns Computed OptLevel
|
||||
static ::OptLevel queryOptLevel(LLILCJitContext &JitContext);
|
||||
|
||||
/// \brief Set UseConservativeGC based on environment variable.
|
||||
///
|
||||
/// \returns true if COMPLUS_GCCONSERVATIVE is set in the environment.
|
||||
static bool queryUseConservativeGC(LLILCJitContext &JitContext);
|
||||
|
||||
/// \brief Set DoInsertStatepoints
|
||||
///
|
||||
/// \returns true if insert statepoints is indicated in the
|
||||
/// environment to model precise GC. (COMPLUS_INSERTSTATEPOINTS)
|
||||
static bool queryDoInsertStatepoints(LLILCJitContext &JitContext);
|
||||
|
||||
/// \brief Set DoTailCallOpt based on environment variable.
|
||||
///
|
||||
/// \returns true if COMPLUS_TAILCALLOPT is set in the environment set.
|
||||
static bool queryDoTailCallOpt(LLILCJitContext &JitContext);
|
||||
|
||||
public:
|
||||
bool IsAltJit; ///< True if running as the alternative JIT.
|
||||
|
||||
private:
|
||||
static MethodSet AltJitMethodSet; ///< Singleton AltJit MethodSet.
|
||||
static MethodSet AltJitNgenMethodSet; ///< Singleton AltJitNgen MethodSet.
|
||||
};
|
||||
|
||||
#endif // JITOPTIONS_H
|
|
@ -1,81 +0,0 @@
|
|||
//===----------------- include/Jit/options.h -------------------*- C++ -*-===//
|
||||
//
|
||||
// LLILC
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
// See LICENSE file in the project root for full license information.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file
|
||||
/// \brief Declaration of the Options class that encapsulates JIT options
|
||||
/// extracted from CoreCLR config values.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef OPTIONS_H
|
||||
#define OPTIONS_H
|
||||
|
||||
#include "utility.h"
|
||||
|
||||
struct LLILCJitContext;
|
||||
|
||||
/// \brief Enum for JIT optimization level.
|
||||
enum OptLevel {
|
||||
INVALID,
|
||||
DEBUG_CODE, ///< No/Low optimization to preserve debug semantics.
|
||||
BLENDED_CODE, ///< Fast code that remains sensitive to code size.
|
||||
SMALL_CODE, ///< Optimized for small size.
|
||||
FAST_CODE ///< Optimized for speed.
|
||||
};
|
||||
|
||||
/// \brief Enum for LLVM IR Dump Level
|
||||
enum LLVMDumpLevel {
|
||||
NODUMP, ///< Do not dump any LLVM IR or summary.
|
||||
SUMMARY, ///< Only dump one line summary per method.
|
||||
VERBOSE ///< Dump full LLVM IR and method summary.
|
||||
};
|
||||
|
||||
/// \brief The JIT options provided via CoreCLR configurations.
|
||||
///
|
||||
/// This class implements the JIT options flags. The CoreCLR interface
|
||||
/// is queried and results are cached in this object.
|
||||
///
|
||||
class Options {
|
||||
public:
|
||||
/// Construct an Options object based on the passed JitContext.
|
||||
Options(LLILCJitContext *Context);
|
||||
|
||||
/// Destruct Options object.
|
||||
~Options();
|
||||
|
||||
// Initialize object after full Context is established.
|
||||
void initialize();
|
||||
|
||||
/// Set current JIT invocation as "AltJit". This sets up
|
||||
/// the JIT to filter based on the AltJit flag contents.
|
||||
void setIsAltJit();
|
||||
|
||||
/// \brief Compute dump level for the JIT
|
||||
///
|
||||
/// Dump level requested via CLR config for the JIT
|
||||
void setDumpLevel();
|
||||
|
||||
/// \brief Set optimization level for the JIT.
|
||||
///
|
||||
/// Opt Level based on CLR provided flags and environment.
|
||||
void setOptLevel();
|
||||
|
||||
public:
|
||||
LLILCJitContext *Context; ///< Invocation CLR Execution Engine flags.
|
||||
LLVMDumpLevel DumpLevel; ///< Dump level for this JIT invocation.
|
||||
::OptLevel OptLevel; ///< Optimization level for this JIT invocation.
|
||||
bool IsAltJit; ///< True if compiling as the alternative JIT.
|
||||
|
||||
private:
|
||||
static MethodSet AltJitMethodSet; ///< Singleton AltJit MethodSet.
|
||||
static MethodSet AltJitNgenMethodSet; ///< Singleton AltJitNgen MethodSet.
|
||||
};
|
||||
|
||||
#endif // OPTIONS_H
|
|
@ -0,0 +1,57 @@
|
|||
//===----------------- include/Jit/options.h -------------------*- C++ -*-===//
|
||||
//
|
||||
// LLILC
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
// See LICENSE file in the project root for full license information.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file
|
||||
/// \brief Declaration of the Options class that encapsulates JIT options
|
||||
/// extracted from CoreCLR config values.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef OPTIONS_H
|
||||
#define OPTIONS_H
|
||||
|
||||
#include "utility.h"
|
||||
|
||||
struct LLILCJitContext;
|
||||
|
||||
/// \brief Enum for JIT optimization level.
|
||||
enum class OptLevel {
|
||||
INVALID,
|
||||
DEBUG_CODE, ///< No/Low optimization to preserve debug semantics.
|
||||
BLENDED_CODE, ///< Fast code that remains sensitive to code size.
|
||||
SMALL_CODE, ///< Optimized for small size.
|
||||
FAST_CODE ///< Optimized for speed.
|
||||
};
|
||||
|
||||
/// \brief Enum for LLVM IR Dump Level
|
||||
enum class DumpLevel {
|
||||
NODUMP, ///< Do not dump any LLVM IR or summary.
|
||||
SUMMARY, ///< Only dump one line summary per method.
|
||||
VERBOSE ///< Dump full LLVM IR and method summary.
|
||||
};
|
||||
|
||||
// Macro to determine the default behavior of automatically
|
||||
// detecting tail calls (without the "tail." opcode in MSIL).
|
||||
#define DEFAULT_TAIL_CALL_OPT 1
|
||||
|
||||
/// \brief The JIT options provided via CoreCLR configurations.
|
||||
///
|
||||
/// This class exposes the JIT options flags. This interface is passed
|
||||
/// around to Options consumers to give them access to the results of
|
||||
/// the ConfigValue queries but no query logic is exposed here.
|
||||
///
|
||||
struct Options {
|
||||
DumpLevel DumpLevel; ///< Dump level for this JIT invocation.
|
||||
OptLevel OptLevel; ///< Optimization level for this JIT invocation.
|
||||
bool UseConservativeGC; ///< True if the environment is set to use CGC.
|
||||
bool DoInsertStatepoints; ///< True if the environment calls for statepoints.
|
||||
bool DoTailCallOpt; ///< Tail call optimization.
|
||||
};
|
||||
#endif // OPTIONS_H
|
|
@ -138,28 +138,6 @@ extern void _cdecl fatal(int Errnum, ...);
|
|||
|
||||
// Environment config variables
|
||||
|
||||
#if !defined(CC_PEVERIFY)
|
||||
extern uint32_t EnvConfigTailCallOpt;
|
||||
#if !defined(NODEBUG)
|
||||
extern uint32_t EnvConfigDebugVerify;
|
||||
extern uint32_t EnvConfigTailCallMax;
|
||||
#endif // !NODEBUG
|
||||
#endif // !CC_PEVERIFY
|
||||
extern uint32_t EnvConfigPInvokeInline;
|
||||
extern uint32_t EnvConfigPInvokeCalliOpt;
|
||||
extern uint32_t EnvConfigTurnOffDebugInfo;
|
||||
|
||||
#if !defined(CC_PEVERIFY)
|
||||
extern bool HaveEnvConfigTailCallOpt;
|
||||
#if !defined(NODEBUG)
|
||||
extern bool HaveEnvConfigDebugVerify;
|
||||
extern bool HaveEnvConfigTailCallMax;
|
||||
#endif // !NODEBUG
|
||||
#endif // !CC_PEVERIFY
|
||||
extern bool HaveEnvConfigPInvokeInline;
|
||||
extern bool HaveEnvConfigPInvokeCalliOpt;
|
||||
extern bool HaveEnvConfigTurnOffDebugInfo;
|
||||
|
||||
#ifdef CC_PEVERIFY
|
||||
extern HRESULT VerLastError;
|
||||
#endif
|
||||
|
@ -1598,6 +1576,14 @@ public:
|
|||
void getMSILInstrStackDelta(ReaderBaseNS::OPCODE Opcode, uint8_t *Operand,
|
||||
uint16_t *Pop, uint16_t *Push);
|
||||
|
||||
/// \brief Check options to as to whether to do the tail call opt
|
||||
///
|
||||
/// Derived class will provide an implementation that is correct for the
|
||||
/// client.
|
||||
///
|
||||
/// \returns true if tail call opt is enabled.
|
||||
virtual bool doTailCallOpt() = 0;
|
||||
|
||||
private:
|
||||
/// \brief Determine if a call instruction is a candidate to be a tail call.
|
||||
///
|
||||
|
|
|
@ -1187,8 +1187,8 @@ private:
|
|||
|
||||
/// Store a value to an argument passed indirectly.
|
||||
///
|
||||
/// The storage backing such arguments may be loacted on the heap; any stores
|
||||
/// to these loactions may need write barriers.
|
||||
/// The storage backing such arguments may be located on the heap; any stores
|
||||
/// to these locations may need write barriers.
|
||||
///
|
||||
/// \param ValueArgType EE type info for the value to store.
|
||||
/// \param ValueToStore The value to store.
|
||||
|
@ -1286,6 +1286,10 @@ private:
|
|||
/// insertion phase.
|
||||
void createSafepointPoll();
|
||||
|
||||
/// \brief Override of doTailCallOpt method
|
||||
/// Provides client specific Options look up.
|
||||
bool doTailCallOpt() override;
|
||||
|
||||
private:
|
||||
LLILCJitContext *JitContext;
|
||||
ABIInfo *TheABIInfo;
|
||||
|
|
|
@ -63,7 +63,7 @@ add_llilcjit_library(
|
|||
jitpch.cpp
|
||||
LLILCJit.cpp
|
||||
EEMemoryManager.cpp
|
||||
options.cpp
|
||||
jitoptions.cpp
|
||||
utility.cpp
|
||||
${LLILCJIT_EXPORTS_DEF}
|
||||
)
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
#include "jitpch.h"
|
||||
#include "LLILCJit.h"
|
||||
#include "options.h"
|
||||
#include "jitoptions.h"
|
||||
#include "readerir.h"
|
||||
#include "abi.h"
|
||||
#include "EEMemoryManager.h"
|
||||
|
@ -45,20 +45,6 @@
|
|||
|
||||
using namespace llvm;
|
||||
|
||||
// Get the GC-Scheme used by the runtime -- conservative/precise
|
||||
// For now this is done by directly accessing environment variable.
|
||||
// When CLR config support is included, update it here.
|
||||
bool shouldUseConservativeGC() {
|
||||
const char *LevelCStr = getenv("COMPLUS_GCCONSERVATIVE");
|
||||
return (LevelCStr != nullptr) && (strcmp(LevelCStr, "1") == 0);
|
||||
}
|
||||
|
||||
// Determine if GC statepoints should be inserted.
|
||||
bool shouldInsertStatepoints() {
|
||||
const char *LevelCStr = getenv("COMPLUS_INSERTSTATEPOINTS");
|
||||
return (LevelCStr != nullptr) && (strcmp(LevelCStr, "1") == 0);
|
||||
}
|
||||
|
||||
// The one and only Jit Object.
|
||||
LLILCJit *LLILCJit::TheJit = nullptr;
|
||||
|
||||
|
@ -89,10 +75,6 @@ LLILCJit::LLILCJit() {
|
|||
InitializeNativeTargetAsmPrinter();
|
||||
InitializeNativeTargetAsmParser();
|
||||
llvm::linkStatepointExampleGC();
|
||||
|
||||
ShouldInsertStatepoints = shouldInsertStatepoints();
|
||||
assert(ShouldInsertStatepoints ||
|
||||
shouldUseConservativeGC() && "Statepoints required for precise-GC");
|
||||
}
|
||||
|
||||
#ifdef LLVM_ON_WIN32
|
||||
|
@ -123,7 +105,7 @@ void LLILCJitContext::outputDebugMethodName() {
|
|||
}
|
||||
|
||||
LLILCJitContext::LLILCJitContext(LLILCJitPerThreadState *PerThreadState)
|
||||
: State(PerThreadState), HasLoadedBitCode(false), Options(this) {
|
||||
: State(PerThreadState), HasLoadedBitCode(false) {
|
||||
this->Next = State->JitContext;
|
||||
State->JitContext = this;
|
||||
}
|
||||
|
@ -171,12 +153,15 @@ CorJitResult LLILCJit::compileMethod(ICorJitInfo *JitInfo,
|
|||
std::unique_ptr<Module> M = Context.getModuleForMethod(MethodInfo);
|
||||
Context.CurrentModule = M.get();
|
||||
Context.CurrentModule->setTargetTriple(LLILC_TARGET_TRIPLE);
|
||||
Context.MethodName = Context.CurrentModule->getModuleIdentifier();
|
||||
Context.TheABIInfo = ABIInfo::get(*Context.CurrentModule);
|
||||
|
||||
// Initialize per invocation JIT options. This should be done after the
|
||||
// rest of the Context is filled out as it has dependencies on Flags and
|
||||
// MethodInfo
|
||||
Context.Options.initialize();
|
||||
// rest of the Context is filled out as it has dependencies on JitInfo,
|
||||
// Flags and MethodInfo.
|
||||
JitOptions JitOptions(Context);
|
||||
|
||||
Context.Options = &JitOptions;
|
||||
|
||||
EngineBuilder Builder(std::move(M));
|
||||
std::string ErrStr;
|
||||
|
@ -190,7 +175,7 @@ CorJitResult LLILCJit::compileMethod(ICorJitInfo *JitInfo,
|
|||
// Statepoint GC does not support FastIsel yet.
|
||||
Options.EnableFastISel = false;
|
||||
|
||||
if (Context.Options.OptLevel != OptLevel::DEBUG_CODE) {
|
||||
if (Context.Options->OptLevel != OptLevel::DEBUG_CODE) {
|
||||
Builder.setOptLevel(CodeGenOpt::Level::Default);
|
||||
} else {
|
||||
Builder.setOptLevel(CodeGenOpt::Level::None);
|
||||
|
@ -212,14 +197,14 @@ CorJitResult LLILCJit::compileMethod(ICorJitInfo *JitInfo,
|
|||
|
||||
// Now jit the method.
|
||||
CorJitResult Result = CORJIT_INTERNALERROR;
|
||||
if (Context.Options.DumpLevel == VERBOSE) {
|
||||
if (Context.Options->DumpLevel == DumpLevel::VERBOSE) {
|
||||
Context.outputDebugMethodName();
|
||||
}
|
||||
bool HasMethod = this->readMethod(&Context);
|
||||
|
||||
if (HasMethod) {
|
||||
|
||||
if (ShouldInsertStatepoints) {
|
||||
if (Context.Options->DoInsertStatepoints) {
|
||||
// If using Precise GC, run the GC-Safepoint insertion
|
||||
// and lowering passes before generating code.
|
||||
legacy::PassManager Passes;
|
||||
|
@ -320,7 +305,7 @@ bool LLILCJit::readMethod(LLILCJitContext *JitContext) {
|
|||
return true;
|
||||
}
|
||||
|
||||
LLVMDumpLevel DumpLevel = JitContext->Options.DumpLevel;
|
||||
DumpLevel DumpLevel = JitContext->Options->DumpLevel;
|
||||
|
||||
LLILCJitPerThreadState *PerThreadState = State.get();
|
||||
GenIR Reader(JitContext, &PerThreadState->ClassTypeMap,
|
||||
|
@ -328,12 +313,12 @@ bool LLILCJit::readMethod(LLILCJitContext *JitContext) {
|
|||
&PerThreadState->BoxedTypeMap, &PerThreadState->ArrayTypeMap,
|
||||
&PerThreadState->FieldIndexMap);
|
||||
|
||||
std::string FuncName = JitContext->CurrentModule->getModuleIdentifier();
|
||||
std::string FuncName = JitContext->MethodName;
|
||||
|
||||
try {
|
||||
Reader.msilToIR();
|
||||
} catch (NotYetImplementedException &Nyi) {
|
||||
if (DumpLevel >= SUMMARY) {
|
||||
if (DumpLevel >= DumpLevel::SUMMARY) {
|
||||
errs() << "Failed to read " << FuncName << '[' << Nyi.reason() << "]\n";
|
||||
}
|
||||
return false;
|
||||
|
@ -342,25 +327,20 @@ bool LLILCJit::readMethod(LLILCJitContext *JitContext) {
|
|||
Function *Func = JitContext->CurrentModule->getFunction(FuncName);
|
||||
bool IsOk = !verifyFunction(*Func, &dbgs());
|
||||
|
||||
assert(IsOk);
|
||||
|
||||
if (IsOk) {
|
||||
if (DumpLevel >= SUMMARY) {
|
||||
if (DumpLevel >= DumpLevel::SUMMARY) {
|
||||
errs() << "Successfully read " << FuncName << '\n';
|
||||
}
|
||||
} else {
|
||||
if (DumpLevel >= SUMMARY) {
|
||||
errs() << "Failed to read " << FuncName << "[verification error]\n";
|
||||
if (DumpLevel >= DumpLevel::SUMMARY) {
|
||||
errs() << "Read " << FuncName << " but failed verification\n";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (DumpLevel == VERBOSE) {
|
||||
if (DumpLevel == DumpLevel::VERBOSE) {
|
||||
Func->dump();
|
||||
}
|
||||
|
||||
JitContext->MethodName = FuncName;
|
||||
|
||||
return IsOk;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,184 @@
|
|||
//===----------------- lib/Jit/options.cpp ----------------------*- C++ -*-===//
|
||||
//
|
||||
// LLILC
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
// See LICENSE file in the project root for full license information.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file
|
||||
/// \brief Definition of the Options class that encapsulates JIT options
|
||||
/// extracted from CoreCLR config values.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "global.h"
|
||||
#include "jitpch.h"
|
||||
#include "LLILCJit.h"
|
||||
#include "jitoptions.h"
|
||||
|
||||
// Define a macro for cross-platform UTF-16 string literals.
|
||||
#if defined(_MSC_VER)
|
||||
#define UTF16(lit) L##lit
|
||||
#else
|
||||
#define UTF16(lit) u##lit
|
||||
#endif
|
||||
|
||||
// For now we're always running as the altjit
|
||||
#define ALT_JIT 1
|
||||
|
||||
// These are the instantiations of the static method sets in Options.h.
|
||||
// This MethodSets are initialized from CLRConfig values passed through
|
||||
// the corinfo.h interface.
|
||||
|
||||
MethodSet JitOptions::AltJitMethodSet;
|
||||
MethodSet JitOptions::AltJitNgenMethodSet;
|
||||
|
||||
template <typename UTF16CharT>
|
||||
char16_t *getStringConfigValue(ICorJitInfo *CorInfo, const UTF16CharT *Name) {
|
||||
static_assert(sizeof(UTF16CharT) == 2, "UTF16CharT is the wrong size!");
|
||||
return (char16_t *)CorInfo->getStringConfigValue((const wchar_t *)Name);
|
||||
}
|
||||
|
||||
template <typename UTF16CharT>
|
||||
void freeStringConfigValue(ICorJitInfo *CorInfo, UTF16CharT *Value) {
|
||||
static_assert(sizeof(UTF16CharT) == 2, "UTF16CharT is the wrong size!");
|
||||
return CorInfo->freeStringConfigValue((wchar_t *)Value);
|
||||
}
|
||||
|
||||
JitOptions::JitOptions(LLILCJitContext &Context) {
|
||||
// Set 'IsAltJit' based on environment information.
|
||||
IsAltJit = queryIsAltJit(Context);
|
||||
|
||||
// Set dump level for this JIT invocation.
|
||||
DumpLevel = queryDumpLevel(Context);
|
||||
|
||||
// Set optimization level for this JIT invocation.
|
||||
OptLevel = queryOptLevel(Context);
|
||||
|
||||
// Set whether to use conservative GC.
|
||||
UseConservativeGC = queryUseConservativeGC(Context);
|
||||
|
||||
// Set whether to insert statepoints.
|
||||
DoInsertStatepoints = queryDoInsertStatepoints(Context);
|
||||
|
||||
// Set whether to do tail call opt.
|
||||
DoTailCallOpt = queryDoTailCallOpt(Context);
|
||||
|
||||
// Validate Statepoint and Conservative GC state.
|
||||
assert(DoInsertStatepoints ||
|
||||
UseConservativeGC && "Statepoints required for precise-GC");
|
||||
}
|
||||
|
||||
bool JitOptions::queryDoTailCallOpt(LLILCJitContext &Context) {
|
||||
return (bool)DEFAULT_TAIL_CALL_OPT;
|
||||
}
|
||||
|
||||
bool JitOptions::queryIsAltJit(LLILCJitContext &Context) {
|
||||
// Initial state is that we are not an alternative jit until proven otherwise;
|
||||
bool IsAlternateJit = false;
|
||||
|
||||
// NDEBUG is !Debug
|
||||
|
||||
#if !defined(NDEBUG)
|
||||
|
||||
// DEBUG case
|
||||
|
||||
// Get/reuse method set that contains the altjit method value.
|
||||
MethodSet *AltJit = nullptr;
|
||||
|
||||
if (Context.Flags & CORJIT_FLG_PREJIT) {
|
||||
if (!AltJitNgenMethodSet.isInitialized()) {
|
||||
char16_t *NgenStr =
|
||||
getStringConfigValue(Context.JitInfo, UTF16("AltJitNgen"));
|
||||
std::unique_ptr<std::string> NgenUtf8 = Convert::utf16ToUtf8(NgenStr);
|
||||
AltJitNgenMethodSet.init(std::move(NgenUtf8));
|
||||
freeStringConfigValue(Context.JitInfo, NgenStr);
|
||||
}
|
||||
// Set up AltJitNgen set to be used for AltJit test.
|
||||
AltJit = &AltJitNgenMethodSet;
|
||||
} else {
|
||||
if (!AltJitMethodSet.isInitialized()) {
|
||||
char16_t *JitStr = getStringConfigValue(Context.JitInfo, UTF16("AltJit"));
|
||||
// Move this to the UTIL code and ifdef it for platform
|
||||
std::unique_ptr<std::string> JitUtf8 = Convert::utf16ToUtf8(JitStr);
|
||||
AltJitMethodSet.init(std::move(JitUtf8));
|
||||
freeStringConfigValue(Context.JitInfo, JitStr);
|
||||
}
|
||||
// Set up AltJit set to be use for AltJit test.
|
||||
AltJit = &AltJitMethodSet;
|
||||
}
|
||||
|
||||
#ifdef ALT_JIT
|
||||
if (AltJit->contains(Context.MethodName.data(), nullptr,
|
||||
Context.MethodInfo->args.pSig)) {
|
||||
IsAlternateJit = true;
|
||||
}
|
||||
#endif // ALT_JIT
|
||||
|
||||
#else
|
||||
if (Context.Flags & CORJIT_FLG_PREJIT) {
|
||||
char16_t *NgenStr =
|
||||
getStringConfigValue(Context.JitInfo, UTF16("AltJitNgen"));
|
||||
std::unique_ptr<std::string> NgenUtf8 = Convert::utf16ToUtf8(NgenStr);
|
||||
if (NgenUtf8->compare("*") == 0) {
|
||||
IsAlternateJit = true;
|
||||
}
|
||||
} else {
|
||||
char16_t *JitStr = getStringConfigValue(Context.JitInfo, UTF16("AltJit"));
|
||||
std::unique_ptr<std::string> JitUtf8 = Convert::utf16ToUtf8(JitStr);
|
||||
if (JitUtf8->compare("*") == 0) {
|
||||
IsAlternateJit = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return IsAlternateJit;
|
||||
}
|
||||
|
||||
::DumpLevel JitOptions::queryDumpLevel(LLILCJitContext &Context) {
|
||||
::DumpLevel JitDumpLevel = DumpLevel::NODUMP;
|
||||
|
||||
char16_t *LevelWStr =
|
||||
getStringConfigValue(Context.JitInfo, UTF16("DUMPLLVMIR"));
|
||||
if (LevelWStr) {
|
||||
std::unique_ptr<std::string> Level = Convert::utf16ToUtf8(LevelWStr);
|
||||
std::transform(Level->begin(), Level->end(), Level->begin(), ::toupper);
|
||||
if (Level->compare("VERBOSE") == 0) {
|
||||
JitDumpLevel = DumpLevel::VERBOSE;
|
||||
} else if (Level->compare("SUMMARY") == 0) {
|
||||
JitDumpLevel = DumpLevel::SUMMARY;
|
||||
}
|
||||
}
|
||||
|
||||
return JitDumpLevel;
|
||||
}
|
||||
|
||||
// Get the GC-Scheme used by the runtime -- conservative/precise
|
||||
bool JitOptions::queryUseConservativeGC(LLILCJitContext &Context) {
|
||||
char16_t *GCStr =
|
||||
getStringConfigValue(Context.JitInfo, UTF16("GCCONSERVATIVE"));
|
||||
return (GCStr != nullptr);
|
||||
}
|
||||
|
||||
// Determine if GC statepoints should be inserted.
|
||||
bool JitOptions::queryDoInsertStatepoints(LLILCJitContext &Context) {
|
||||
char16_t *StatePointStr =
|
||||
getStringConfigValue(Context.JitInfo, UTF16("INSERTSTATEPOINTS"));
|
||||
return (StatePointStr != nullptr);
|
||||
}
|
||||
|
||||
OptLevel JitOptions::queryOptLevel(LLILCJitContext &Context) {
|
||||
::OptLevel JitOptLevel = OptLevel::INVALID;
|
||||
// Currently we only check for the debug flag but this will be extended
|
||||
// to account for further opt levels as we move forward.
|
||||
if ((Context.Flags & CORJIT_FLG_DEBUG_CODE) != 0) {
|
||||
JitOptLevel = OptLevel::DEBUG_CODE;
|
||||
}
|
||||
|
||||
return JitOptLevel;
|
||||
}
|
||||
|
||||
JitOptions::~JitOptions() {}
|
|
@ -1,146 +0,0 @@
|
|||
//===----------------- lib/Jit/options.cpp ----------------------*- C++ -*-===//
|
||||
//
|
||||
// LLILC
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
// See LICENSE file in the project root for full license information.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file
|
||||
/// \brief Definition of the Options class that encapsulates JIT options
|
||||
/// extracted from CoreCLR config values.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "global.h"
|
||||
#include "jitpch.h"
|
||||
#include "LLILCJit.h"
|
||||
#include "options.h"
|
||||
|
||||
// Define a macro for cross-platform UTF-16 string literals.
|
||||
#if defined(_MSC_VER)
|
||||
#define UTF16(lit) L##lit
|
||||
#else
|
||||
#define UTF16(lit) u##lit
|
||||
#endif
|
||||
|
||||
// For now we're always running as the altjit
|
||||
#define ALT_JIT 1
|
||||
|
||||
// These are the instantiations of the static method sets in Options.h.
|
||||
// This MethodSets are initialized from CLRConfig values passed through
|
||||
// the corinfo.h interface.
|
||||
|
||||
MethodSet Options::AltJitMethodSet;
|
||||
MethodSet Options::AltJitNgenMethodSet;
|
||||
|
||||
template <typename UTF16CharT>
|
||||
char16_t *getStringConfigValue(ICorJitInfo *CorInfo, const UTF16CharT *Name) {
|
||||
static_assert(sizeof(UTF16CharT) == 2, "UTF16CharT is the wrong size!");
|
||||
return (char16_t *)CorInfo->getStringConfigValue((const wchar_t *)Name);
|
||||
}
|
||||
|
||||
template <typename UTF16CharT>
|
||||
void freeStringConfigValue(ICorJitInfo *CorInfo, UTF16CharT *Value) {
|
||||
static_assert(sizeof(UTF16CharT) == 2, "UTF16CharT is the wrong size!");
|
||||
return CorInfo->freeStringConfigValue((wchar_t *)Value);
|
||||
}
|
||||
|
||||
Options::Options(LLILCJitContext *Context) : Context(Context) {}
|
||||
|
||||
void Options::initialize() {
|
||||
// Set 'IsAltJit' based on environment information.
|
||||
setIsAltJit();
|
||||
|
||||
// Set dump level for this JIT invocation.
|
||||
setDumpLevel();
|
||||
|
||||
// Set optimization level for this JIT invocation.
|
||||
setOptLevel();
|
||||
}
|
||||
|
||||
void Options::setIsAltJit() {
|
||||
// Initial state is that we are not an alternative jit until proven otherwise;
|
||||
|
||||
IsAltJit = false;
|
||||
|
||||
// NDEBUG is !Debug
|
||||
|
||||
#if !defined(NDEBUG)
|
||||
|
||||
// DEBUG case
|
||||
|
||||
// Get/reuse method set that contains the altjit method value.
|
||||
MethodSet *AltJit = nullptr;
|
||||
|
||||
if (Context->Flags & CORJIT_FLG_PREJIT) {
|
||||
char16_t *NgenStr =
|
||||
getStringConfigValue(Context->JitInfo, UTF16("AltJitNgen"));
|
||||
std::unique_ptr<std::string> NgenUtf8 = Convert::utf16ToUtf8(NgenStr);
|
||||
AltJitNgenMethodSet.init(std::move(NgenUtf8));
|
||||
freeStringConfigValue(Context->JitInfo, NgenStr);
|
||||
AltJit = &AltJitNgenMethodSet;
|
||||
} else {
|
||||
char16_t *JitStr = getStringConfigValue(Context->JitInfo, UTF16("AltJit"));
|
||||
// Move this to the UTIL code and ifdef it for platform
|
||||
std::unique_ptr<std::string> JitUtf8 = Convert::utf16ToUtf8(JitStr);
|
||||
AltJitMethodSet.init(std::move(JitUtf8));
|
||||
freeStringConfigValue(Context->JitInfo, JitStr);
|
||||
AltJit = &AltJitMethodSet;
|
||||
}
|
||||
|
||||
#ifdef ALT_JIT
|
||||
if (AltJit->contains(Context->MethodName.data(), nullptr,
|
||||
Context->MethodInfo->args.pSig)) {
|
||||
IsAltJit = true;
|
||||
}
|
||||
#endif // ALT_JIT
|
||||
|
||||
#else
|
||||
if (Context->Flags & CORJIT_FLG_PREJIT) {
|
||||
char16_t *NgenStr =
|
||||
getStringConfigValue(Context->JitInfo, UTF16("AltJitNgen"));
|
||||
std::unique_ptr<std::string> NgenUtf8 = Convert::utf16ToUtf8(NgenStr);
|
||||
if (NgenUtf8->compare("*") == 0) {
|
||||
IsAltJit = true;
|
||||
}
|
||||
} else {
|
||||
char16_t *JitStr = getStringConfigValue(Context->JitInfo, UTF16("AltJit"));
|
||||
std::unique_ptr<std::string> JitUtf8 = Convert::utf16ToUtf8(JitStr);
|
||||
if (JitUtf8->compare("*") == 0) {
|
||||
IsAltJit = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void Options::setDumpLevel() {
|
||||
char16_t *LevelWStr =
|
||||
getStringConfigValue(Context->JitInfo, UTF16("DUMPLLVMIR"));
|
||||
if (LevelWStr) {
|
||||
std::unique_ptr<std::string> Level = Convert::utf16ToUtf8(LevelWStr);
|
||||
std::transform(Level->begin(), Level->end(), Level->begin(), ::toupper);
|
||||
if (Level->compare("VERBOSE") == 0) {
|
||||
DumpLevel = VERBOSE;
|
||||
return;
|
||||
}
|
||||
if (Level->compare("SUMMARY") == 0) {
|
||||
DumpLevel = SUMMARY;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
DumpLevel = NODUMP;
|
||||
}
|
||||
|
||||
void Options::setOptLevel() {
|
||||
// Currently we only check for the debug flag but this will be extended
|
||||
// to account for further opt levels as we move forward.
|
||||
if ((Context->Flags & CORJIT_FLG_DEBUG_CODE) != 0) {
|
||||
OptLevel = ::OptLevel::DEBUG_CODE;
|
||||
}
|
||||
}
|
||||
|
||||
Options::~Options() {}
|
|
@ -238,7 +238,7 @@ Function *ABIMethodSignature::createFunction(GenIR &Reader, Module &M) {
|
|||
}
|
||||
F->setCallingConv(CC);
|
||||
|
||||
if (LLILCJit::TheJit->ShouldInsertStatepoints) {
|
||||
if (Reader.JitContext->Options->DoInsertStatepoints) {
|
||||
F->setGC("statepoint-example");
|
||||
}
|
||||
|
||||
|
|
|
@ -42,45 +42,6 @@ extern int _cdecl dbPrint(const char *Form, ...);
|
|||
// Max elements per entry in FlowGraphNodeListArray.
|
||||
#define FLOW_GRAPH_NODE_LIST_ARRAY_STRIDE 32
|
||||
|
||||
// Macro to determine the default behavior of automatically
|
||||
// detecting tail calls (without the "tail." opcode in MSIL).
|
||||
#define DEFAULT_TAIL_CALL_OPT 1
|
||||
|
||||
static uint32_t doTailCallOpt() {
|
||||
#ifndef CC_PEVERIFY
|
||||
if (HaveEnvConfigTailCallOpt) {
|
||||
return EnvConfigTailCallOpt;
|
||||
}
|
||||
return DEFAULT_TAIL_CALL_OPT;
|
||||
#else
|
||||
return 0;
|
||||
#endif // !CC_PEVERIFY
|
||||
}
|
||||
|
||||
#ifndef NODEBUG
|
||||
static bool checkTailCallMax() {
|
||||
#ifndef CC_PEVERIFY
|
||||
uint32_t TailCallMax = 0;
|
||||
static uint32_t TailCallCount = 0;
|
||||
|
||||
if (HaveEnvConfigTailCallMax) {
|
||||
TailCallMax = EnvConfigTailCallMax;
|
||||
}
|
||||
|
||||
if (TailCallMax) {
|
||||
if (++TailCallCount > TailCallMax) {
|
||||
return false;
|
||||
}
|
||||
dbPrint("**** TailCallCount = %d\n", TailCallCount);
|
||||
}
|
||||
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
#endif // !NODEBUG
|
||||
|
||||
#define CANONICAL_EXIT_INIT_VAL (-2)
|
||||
|
||||
// OPCODE REMAP
|
||||
|
@ -6356,13 +6317,6 @@ bool ReaderBase::isUnmarkedTailCallHelper(uint8_t *ILInput,
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef NODEBUG
|
||||
if (!checkTailCallMax()) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -279,7 +279,7 @@ void GenIR::readerPrePass(uint8_t *Buffer, uint32_t NumBytes) {
|
|||
ASSERTNR(UNREACHED);
|
||||
}
|
||||
|
||||
if (LLILCJit::TheJit->ShouldInsertStatepoints) {
|
||||
if (JitContext->Options->DoInsertStatepoints) {
|
||||
createSafepointPoll();
|
||||
}
|
||||
|
||||
|
@ -451,7 +451,7 @@ void GenIR::readerPostPass(bool IsImportOnly) {
|
|||
insertIRForSecurityObject();
|
||||
}
|
||||
|
||||
if (LLILCJit::TheJit->ShouldInsertStatepoints) {
|
||||
if (JitContext->Options->DoInsertStatepoints) {
|
||||
|
||||
// Precise GC using statepoints cannot handle aggregates that contain
|
||||
// managed pointers yet. So, check if this function deals with such values
|
||||
|
@ -771,6 +771,8 @@ void GenIR::createSafepointPoll() {
|
|||
ReturnInst::Create(*LLVMContext, EntryBlock);
|
||||
}
|
||||
|
||||
bool GenIR::doTailCallOpt() { return JitContext->Options->DoTailCallOpt; }
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region DIAGNOSTICS
|
||||
|
|
Загрузка…
Ссылка в новой задаче