Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions src/coreclr/inc/corinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -1636,6 +1636,17 @@ struct CORINFO_EH_CLAUSE
};
};

enum CorInfoArch
{
CORINFO_ARCH_X86 = 0x014c,
CORINFO_ARCH_X64 = 0x8664,
CORINFO_ARCH_ARM = 0x01c4,
CORINFO_ARCH_ARM64 = 0xaa64,
CORINFO_ARCH_LOONGARCH64 = 0x6264,
CORINFO_ARCH_RISCV64 = 0x5064,
CORINFO_ARCH_WASM32,
};

enum CORINFO_OS
{
CORINFO_WINNT,
Expand Down
6 changes: 3 additions & 3 deletions src/coreclr/inc/corjit.h
Original file line number Diff line number Diff line change
Expand Up @@ -432,9 +432,9 @@ class ICorJitInfo : public ICorDynamicInfo
virtual uint16_t getRelocTypeHint(void * target) = 0;

// For what machine does the VM expect the JIT to generate code? The VM
// returns one of the IMAGE_FILE_MACHINE_* values. Note that if the VM
// is cross-compiling (such as the case for crossgen), it will return a
// different value than if it was compiling for the host architecture.
// returns one of the CorInfoArch values. Note that if the VM is cross
// compiling (such as the case for crossgen), it will return a different
// value than if it was compiling for the host architecture.
//
virtual uint32_t getExpectedTargetArchitecture() = 0;

Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/jit/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,7 @@ set( JIT_WASM_SOURCES
emitwasm.cpp
lowerwasm.cpp
regallocwasm.cpp
registeropswasm.cpp
targetwasm.cpp
)

Expand Down Expand Up @@ -471,6 +472,7 @@ set( JIT_RISCV64_HEADERS

set( JIT_WASM_HEADERS
regallocwasm.h
registeropswasm.h
targetwasm.h
emitwasm.h
emitfmtswasm.h
Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/jit/abi.h
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,8 @@ class LoongArch64Classifier

class WasmClassifier
{
unsigned m_localIndex = 0;

public:
WasmClassifier(const ClassifierInfo& info);

Expand Down
6 changes: 3 additions & 3 deletions src/coreclr/jit/codegencommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2156,7 +2156,7 @@ void CodeGen::genEmitMachineCode()
#if TRACK_LSRA_STATS
if (JitConfig.DisplayLsraStats() == 3)
{
compiler->m_pLinearScan->dumpLsraStatsSummary(jitstdout());
compiler->m_regAlloc->dumpLsraStatsSummary(jitstdout());
}
#endif // TRACK_LSRA_STATS

Expand Down Expand Up @@ -4526,7 +4526,7 @@ void CodeGen::genFinalizeFrame()
// of the first basic block, so load those up. In particular, the determination
// of whether or not to use block init in the prolog is dependent on the variable
// locations on entry to the function.
compiler->m_pLinearScan->recordVarLocationsAtStartOfBB(compiler->fgFirstBB);
compiler->m_regAlloc->recordVarLocationsAtStartOfBB(compiler->fgFirstBB);

genCheckUseBlockInit();

Expand Down Expand Up @@ -5843,7 +5843,7 @@ void CodeGen::genGeneratePrologsAndEpilogs()

// Before generating the prolog, we need to reset the variable locations to what they will be on entry.
// This affects our code that determines which untracked locals need to be zero initialized.
compiler->m_pLinearScan->recordVarLocationsAtStartOfBB(compiler->fgFirstBB);
compiler->m_regAlloc->recordVarLocationsAtStartOfBB(compiler->fgFirstBB);

// Tell the emitter we're done with main code generation, and are going to start prolog and epilog generation.

Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/jit/codegenlinear.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ void CodeGen::genCodeForBBlist()
gcInfo.gcRegGCrefSetCur = RBM_NONE;
gcInfo.gcRegByrefSetCur = RBM_NONE;

compiler->m_pLinearScan->recordVarLocationsAtStartOfBB(block);
compiler->m_regAlloc->recordVarLocationsAtStartOfBB(block);

// Updating variable liveness after last instruction of previous block was emitted
// and before first of the current block is emitted
Expand Down
14 changes: 7 additions & 7 deletions src/coreclr/jit/compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,7 @@ Compiler::Compiler(ArenaAllocator* arena,
// Do we have a matched VM? Or are we "abusing" the VM to help us do JIT work (such as using an x86 native VM
// with an ARM-targeting "altjit").
// Match CPU/ABI for compMatchedVM
info.compMatchedVM = IMAGE_FILE_MACHINE_TARGET == info.compCompHnd->getExpectedTargetArchitecture();
info.compMatchedVM = info.compCompHnd->getExpectedTargetArchitecture() == CORINFO_ARCH_TARGET;

// Match OS for compMatchedVM
CORINFO_EE_INFO* eeInfo = eeGetEEInfo();
Expand Down Expand Up @@ -4965,14 +4965,14 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl

// Assign registers to variables, etc.

// Create LinearScan before Lowering, so that Lowering can call LinearScan methods
// for determining whether locals are register candidates and (for xarch) whether
// Create the RA before Lowering, so that Lowering can call RA methods for
// determining whether locals are register candidates and (for xarch) whether
// a node is a containable memory op.
m_pLinearScan = getLinearScanAllocator(this);
m_regAlloc = GetRegisterAllocator(this);

// Lower
//
m_pLowering = new (this, CMK_LSRA) Lowering(this, m_pLinearScan); // PHASE_LOWERING
m_pLowering = new (this, CMK_LSRA) Lowering(this, m_regAlloc); // PHASE_LOWERING
m_pLowering->Run();

// Set stack levels and analyze throw helper usage.
Expand All @@ -4988,7 +4988,7 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl
// Now that lowering is completed we can proceed to perform register allocation
//
auto linearScanPhase = [this] {
m_pLinearScan->doLinearScan();
m_regAlloc->doRegisterAllocation();
};
DoPhase(this, PHASE_LINEAR_SCAN, linearScanPhase);

Expand Down Expand Up @@ -5037,7 +5037,7 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl
#if TRACK_LSRA_STATS
if (JitConfig.DisplayLsraStats() == 2)
{
m_pLinearScan->dumpLsraStatsCsv(jitstdout());
m_regAlloc->dumpLsraStatsCsv(jitstdout());
}
#endif // TRACK_LSRA_STATS

Expand Down
12 changes: 6 additions & 6 deletions src/coreclr/jit/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -1363,10 +1363,10 @@ enum class PhaseStatus : unsigned
};

// interface to hide linearscan implementation from rest of compiler
class LinearScanInterface
class RegAllocInterface
{
public:
virtual PhaseStatus doLinearScan() = 0;
virtual PhaseStatus doRegisterAllocation() = 0;
virtual void recordVarLocationsAtStartOfBB(BasicBlock* bb) = 0;
virtual bool willEnregisterLocalVars() const = 0;
#if TRACK_LSRA_STATS
Expand All @@ -1375,7 +1375,7 @@ class LinearScanInterface
#endif // TRACK_LSRA_STATS
};

LinearScanInterface* getLinearScanAllocator(Compiler* comp);
RegAllocInterface* GetRegisterAllocator(Compiler* comp);

// This enumeration names the phases into which we divide compilation. The phases should completely
// partition a compilation.
Expand Down Expand Up @@ -5577,7 +5577,7 @@ class Compiler

bool backendRequiresLocalVarLifetimes()
{
return !opts.MinOpts() || m_pLinearScan->willEnregisterLocalVars();
return !opts.MinOpts() || m_regAlloc->willEnregisterLocalVars();
}

void fgLocalVarLiveness();
Expand Down Expand Up @@ -8237,8 +8237,8 @@ class Compiler
bool rpMustCreateEBPFrame(INDEBUG(const char** wbReason));

private:
Lowering* m_pLowering = nullptr; // Lowering; needed to Lower IR that's added or modified after Lowering.
LinearScanInterface* m_pLinearScan = nullptr; // Linear Scan allocator
Lowering* m_pLowering = nullptr; // Lowering; needed to Lower IR that's added or modified after Lowering.
RegAllocInterface* m_regAlloc = nullptr; // Register allocator

public:
ArrayStack<ParameterRegisterLocalMapping>* m_paramRegLocalMappings = nullptr;
Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/jit/emit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10317,6 +10317,7 @@ void emitter::emitStackPushLargeStk(BYTE* addr, GCtype gcType, unsigned count)

void emitter::emitStackPopLargeStk(BYTE* addr, bool isCall, unsigned char callInstrSize, unsigned count)
{
#if EMIT_GENERATE_GCINFO
assert(emitIssuing);

unsigned argStkCnt;
Expand Down Expand Up @@ -10421,6 +10422,7 @@ void emitter::emitStackPopLargeStk(BYTE* addr, bool isCall, unsigned char callIn
regPtrNext->rpdArg = true;
regPtrNext->rpdArgType = (unsigned short)GCInfo::rpdARG_POP;
regPtrNext->rpdPtrArg = argRecCnt.Value();
#endif // EMIT_GENERATE_GCINFO
}

/*****************************************************************************
Expand Down
5 changes: 3 additions & 2 deletions src/coreclr/jit/gentree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31335,10 +31335,11 @@ regNumber ReturnTypeDesc::GetABIReturnReg(unsigned idx, CorInfoCallConvExtension
resultReg = varTypeIsIntegralOrI(GetReturnRegType(0)) ? REG_FLOATRET : REG_FLOATRET_1; // FA0 or FA1
}
}
#endif

#endif // TARGET_XXX

#if HAS_FIXED_REGISTER_SET
assert(resultReg != REG_NA);
#endif
return resultReg;
}

Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/jit/gentree.h
Original file line number Diff line number Diff line change
Expand Up @@ -970,7 +970,7 @@ struct GenTree

void SetRegNum(regNumber reg)
{
assert(reg >= REG_FIRST && reg <= REG_COUNT);
genIsValidReg(reg);
_gtRegNum = (regNumberSmall)reg;
INDEBUG(gtRegTag = GT_REGTAG_REG;)
assert(_gtRegNum == reg);
Expand Down
25 changes: 0 additions & 25 deletions src/coreclr/jit/jit.h
Original file line number Diff line number Diff line change
Expand Up @@ -302,31 +302,6 @@
#endif
#endif

// --------------------------------------------------------------------------------
// IMAGE_FILE_MACHINE_TARGET
// --------------------------------------------------------------------------------

#if defined(TARGET_X86)
#define IMAGE_FILE_MACHINE_TARGET IMAGE_FILE_MACHINE_I386
#elif defined(TARGET_AMD64)
#define IMAGE_FILE_MACHINE_TARGET IMAGE_FILE_MACHINE_AMD64
#elif defined(TARGET_ARM)
#define IMAGE_FILE_MACHINE_TARGET IMAGE_FILE_MACHINE_ARMNT
#elif defined(TARGET_ARM64)
#define IMAGE_FILE_MACHINE_TARGET IMAGE_FILE_MACHINE_ARM64 // 0xAA64
#elif defined(TARGET_LOONGARCH64)
#define IMAGE_FILE_MACHINE_TARGET IMAGE_FILE_MACHINE_LOONGARCH64 // 0x6264
#elif defined(TARGET_RISCV64)
#define IMAGE_FILE_MACHINE_TARGET IMAGE_FILE_MACHINE_RISCV64 // 0x5064
#elif defined(TARGET_WASM32)
// TODO-WASM: refactor the Jit-EE interface (getExpectedTargetArchitecture) to stop relying on constants from the PE
// spec for this.
// TODO-Cleanup: move the defines to target<name>.h files.
#define IMAGE_FILE_MACHINE_TARGET 0
#else
#error Unsupported or unset target architecture
#endif

typedef ptrdiff_t ssize_t;

// Include the AMD64 unwind codes when appropriate.
Expand Down
14 changes: 7 additions & 7 deletions src/coreclr/jit/lower.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,23 +29,23 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
class Lowering final : public Phase
{
public:
inline Lowering(Compiler* compiler, LinearScanInterface* lsra)
inline Lowering(Compiler* compiler, RegAllocInterface* regAlloc)
: Phase(compiler, PHASE_LOWERING)
, vtableCallTemp(BAD_VAR_NUM)
#ifdef TARGET_ARM64
, m_blockIndirs(compiler->getAllocator(CMK_ArrayStack))
#endif
{
m_lsra = (LinearScan*)lsra;
assert(m_lsra);
m_regAlloc = static_cast<RegAllocImpl*>(regAlloc);
assert(m_regAlloc != nullptr);
}
virtual PhaseStatus DoPhase() override;

// This variant of LowerRange is called from outside of the main Lowering pass,
// so it creates its own instance of Lowering to do so.
void LowerRange(BasicBlock* block, LIR::ReadOnlyRange& range)
{
Lowering lowerer(comp, m_lsra);
Lowering lowerer(comp, m_regAlloc);
lowerer.m_block = block;

lowerer.LowerRange(range);
Expand Down Expand Up @@ -489,7 +489,7 @@ class Lowering final : public Phase
// Return true if 'node' is a containable memory op.
bool IsContainableMemoryOp(GenTree* node) const
{
return m_lsra->isContainableMemoryOp(node);
return m_regAlloc->isContainableMemoryOp(node);
}

// Return true if 'childNode' is a containable memory op by its size relative to the 'parentNode'.
Expand Down Expand Up @@ -594,14 +594,14 @@ class Lowering final : public Phase
// do an expensive check here. For non-candidates it is not harmful to set lvDoNotEnregister.
if (varDsc->lvTracked && !varDsc->lvDoNotEnregister)
{
assert(!m_lsra->isRegCandidate(varDsc));
assert(!m_regAlloc->isRegCandidate(varDsc));
comp->lvaSetVarDoNotEnregister(lclNum DEBUG_ARG(DoNotEnregisterReason::LocalField));
}
}

void RequireOutgoingArgSpace(GenTree* node, unsigned numBytes);

LinearScan* m_lsra;
RegAllocImpl* m_regAlloc;
unsigned vtableCallTemp; // local variable we use as a temp for vtable calls
mutable SideEffectSet m_scratchSideEffects; // SideEffectSet used for IsSafeToContainMem and isRMWIndirCandidate
BasicBlock* m_block;
Expand Down
8 changes: 4 additions & 4 deletions src/coreclr/jit/lsra.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
That is, the destination register is one of the sources. In this case, we must not use the same register for
the non-RMW operand as for the destination.

Overview (doLinearScan):
Overview (doRegisterAllocation):
- Walk all blocks, building intervals and RefPositions (buildIntervals)
- Allocate registers (allocateRegisters)
- Annotate nodes with register assignments (resolveRegisters)
Expand Down Expand Up @@ -824,7 +824,7 @@ void LinearScan::dumpOutVarToRegMap(BasicBlock* block)

#endif // DEBUG

LinearScanInterface* getLinearScanAllocator(Compiler* comp)
RegAllocInterface* GetRegisterAllocator(Compiler* comp)
{
return new (comp, CMK_LSRA) LinearScan(comp);
}
Expand Down Expand Up @@ -1314,15 +1314,15 @@ BasicBlock* LinearScan::getNextBlock()
}

//------------------------------------------------------------------------
// doLinearScan: The main method for register allocation.
// doRegisterAllocation: The main method for register allocation.
//
// Arguments:
// None
//
// Return Value:
// Suitable phase status
//
PhaseStatus LinearScan::doLinearScan()
PhaseStatus LinearScan::doRegisterAllocation()
{
// Check to see whether we have any local variables to enregister.
// We initialize this in the constructor based on opt settings,
Expand Down
6 changes: 4 additions & 2 deletions src/coreclr/jit/lsra.h
Original file line number Diff line number Diff line change
Expand Up @@ -622,7 +622,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
// to the next RefPosition in code order
// THIS IS THE OPTION CURRENTLY BEING PURSUED

class LinearScan : public LinearScanInterface
class LinearScan : public RegAllocInterface
{
friend class RefPosition;
friend class Interval;
Expand All @@ -634,7 +634,7 @@ class LinearScan : public LinearScanInterface
LinearScan(Compiler* theCompiler);

// This is the main driver
virtual PhaseStatus doLinearScan();
virtual PhaseStatus doRegisterAllocation();

static bool isSingleRegister(SingleTypeRegSet regMask)
{
Expand Down Expand Up @@ -2199,6 +2199,8 @@ class LinearScan : public LinearScanInterface
}
};

using RegAllocImpl = LinearScan;

/*XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XX XX
Expand Down
1 change: 0 additions & 1 deletion src/coreclr/jit/regalloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,4 @@ enum CanDoubleAlign
DEFAULT_DOUBLE_ALIGN = CAN_DOUBLE_ALIGN
};
#endif

#endif // REGALLOC_H_
Loading
Loading