diff options
author | Pat Gavlin <pgavlin@gmail.com> | 2016-08-19 10:44:46 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-08-19 10:44:46 -0700 |
commit | 738f93e7baf5aef7639cdd4567e9cb1746aed619 (patch) | |
tree | 425681f48e72df83235e2a77a6c84cb93bed3927 /src/jit/lsra.h | |
parent | 00c85b302a078d5d13cfe9ff8cb453cd8296d6aa (diff) | |
download | coreclr-738f93e7baf5aef7639cdd4567e9cb1746aed619.tar.gz coreclr-738f93e7baf5aef7639cdd4567e9cb1746aed619.tar.bz2 coreclr-738f93e7baf5aef7639cdd4567e9cb1746aed619.zip |
Implement the proposed design for RyuJIT's LIR. (#6689)
These changes implement the design for RyuJIT's LIR described in https://github.com/dotnet/coreclr/blob/master/Documentation/design-docs/removing-embedded-statements.md.
The following passes required changes:
Rationalize, which has been almost completely rewritten
Long decomposition
Target-independent lowering
Target-dependent lowering
LSRA
Liveness
Flowgraph optimization
Codegen
For the most part, these changes are confined to the backend. Common code that needed to be updated included liveness, flowgraph optimization, and a few miscellaneous utilities.
The utilities used to analyze and manipulate LIR live (almost) entirely in src/jit/lir.{cpp,h}. The core concepts that are unique to LIR are LIR::Use and LIR::Range. The latter is a tuple that captures an SDSU def (i.e. an LIR node) and its corresponding use->def edge and user. The former serves to abstract a self-contained sequence of LIR nodes that make up e.g. the contents of a basic block.
Testing indicates that neither JIT throughput nor code quality are significantly impacted by these changes.
Diffstat (limited to 'src/jit/lsra.h')
-rw-r--r-- | src/jit/lsra.h | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/src/jit/lsra.h b/src/jit/lsra.h index 05d6ecf16d..a3c41fe1e3 100644 --- a/src/jit/lsra.h +++ b/src/jit/lsra.h @@ -398,7 +398,7 @@ public: // Insert a copy in the case where a tree node value must be moved to a different // register at the point of use, or it is reloaded to a different register // than the one it was spilled from - void insertCopyOrReload(GenTreePtr tree, unsigned multiRegIdx, RefPosition* refPosition); + void insertCopyOrReload(BasicBlock* block, GenTreePtr tree, unsigned multiRegIdx, RefPosition* refPosition); #if FEATURE_PARTIAL_SIMD_CALLEE_SAVE // Insert code to save and restore the upper half of a vector that lives @@ -613,8 +613,12 @@ private: void lsraDumpIntervals(const char* msg); void dumpRefPositions(const char* msg); void dumpVarRefPositions(const char* msg); + + static bool IsResolutionMove(GenTree* node); + static bool IsResolutionNode(LIR::Range& containingRange, GenTree* node); + void verifyFinalAllocation(); - void verifyResolutionMove(GenTreeStmt* resolutionStmt, LsraLocation currentLocation); + void verifyResolutionMove(GenTree* resolutionNode, LsraLocation currentLocation); #else // !DEBUG bool doSelectNearest() { @@ -743,6 +747,7 @@ private: // Return the registers killed by the given tree node. regMaskTP getKillSetForNode(GenTree* tree); + // Given some tree node add refpositions for all the registers this node kills bool buildKillPositionsForNode(GenTree* tree, LsraLocation currentLoc); @@ -770,7 +775,7 @@ private: void buildInternalRegisterUsesForNode(GenTree* tree, LsraLocation currentLoc, RefPosition* defs[], int total); - void resolveLocalRef(GenTreePtr treeNode, RefPosition* currentRefPosition); + void resolveLocalRef(BasicBlock* block, GenTreePtr treeNode, RefPosition* currentRefPosition); void insertMove(BasicBlock* block, GenTreePtr insertionPoint, unsigned lclNum, regNumber inReg, regNumber outReg); @@ -931,6 +936,11 @@ private: char* operandString, unsigned operandStringLength); void lsraDispNode(GenTreePtr tree, LsraTupleDumpMode mode, bool hasDest); + void DumpOperandDefs(GenTree* operand, + bool& first, + LsraTupleDumpMode mode, + char* operandString, + const unsigned operandStringLength); void TupleStyleDump(LsraTupleDumpMode mode); bool dumpTerse; |