Merge pull request #482 from russellhadley/SplitOptionsClass

Add Reader required options
This commit is contained in:
Russell C Hadley 2015-04-22 21:39:46 -07:00
Родитель aeed7e864c 93b82adac6
Коммит ef5ebebd32
13 изменённых файлов: 363 добавлений и 345 удалений

Просмотреть файл

@ -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;

83
include/Jit/jitoptions.h Normal file
Просмотреть файл

@ -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

57
include/Reader/options.h Normal file
Просмотреть файл

@ -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;
}

184
lib/Jit/jitoptions.cpp Normal file
Просмотреть файл

@ -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