summaryrefslogtreecommitdiff
path: root/src/jit/block.cpp
diff options
context:
space:
mode:
authorAndy Ayers <andya@microsoft.com>2016-01-06 09:49:23 -0800
committerAndy Ayers <andya@microsoft.com>2016-01-07 12:05:35 -0800
commitb6ed20b4c0ba3bf877a305c44864a32786e905ea (patch)
treeba8ce037c548b4d832a1b0874b39859fc3d4a45a /src/jit/block.cpp
parente8d94bca0185e621c20b2923f2536729eedebef9 (diff)
downloadcoreclr-b6ed20b4c0ba3bf877a305c44864a32786e905ea.tar.gz
coreclr-b6ed20b4c0ba3bf877a305c44864a32786e905ea.tar.bz2
coreclr-b6ed20b4c0ba3bf877a305c44864a32786e905ea.zip
Initial version of the inline tree
Extend `inlExpLst` to to describe the full inlining tree in a method, with a corresponding dump method. Add a top-level tree node to serve as the root of the tree. Set this as the inline context for all top-level expressions. Update the code that links in new nodes when there is a successful inline to build the tree links. Since the child list is extended by a prepend and candidates are currently visited in lexical (increasing "local" IL offset) order, the child list ends up reversed. The dumper prints the list entries from back to front to compensate so the tree display reflects lexical order. Capture IL offset to help in identifying call sites. Note this is incomplete and offets are often missing copies of the parent's offset. Will work on improving this subsequently. Update the depth check to return the depth. This is currently only used in diagnostic messages. Remove some unused inlining-related data members from the compiler class. Cache the `JitPrintInlinedMethods` config value and use it to dump the tree when inlining is done, if there were any inlines. The jit traditionally (and probably inadvertently) allowed one level of recursive inlining. Added a test case showing how this can happen. Because there is now a top-level inlining context, the recursion check can now potentially detect and block these recursive inlines. Support legacy behavior for now by setting `ixlCode` to `nullptr` in the top-level record. This change should be no diff. Sample output: ``` Inlines into Enumerable:Where(ref,ref):ref [IL=3] Error:ArgumentNull(ref):ref [IL=17] Error:ArgumentNull(ref):ref [IL=?] WhereArrayIterator`1:.ctor(ref,ref):this [IL=?] Iterator`1:.ctor():this [IL=?] Object:.ctor():this [IL=?] Environment:get_CurrentManagedThreadId():int [IL=?] Thread:get_CurrentThread():ref [IL=?] WhereListIterator`1:.ctor(ref,ref):this [IL=?] Iterator`1:.ctor():this [IL=?] Object:.ctor():this [IL=?] Environment:get_CurrentManagedThreadId():int [IL=?] Thread:get_CurrentThread():ref [IL=?] WhereEnumerableIterator`1:.ctor(ref,ref):this [IL=?] Iterator`1:.ctor():this [IL=?] Object:.ctor():this [IL=?] Environment:get_CurrentManagedThreadId():int [IL=?] Thread:get_CurrentThread():ref ``` Sample showing the recursive inline: ``` Inlines into Fact:factRx(int,int,int,int):int [IL=6] Fact:factRx(int,int,int,int):int ```
Diffstat (limited to 'src/jit/block.cpp')
-rw-r--r--src/jit/block.cpp66
1 files changed, 66 insertions, 0 deletions
diff --git a/src/jit/block.cpp b/src/jit/block.cpp
index 15e6df01c4..9149bbe11b 100644
--- a/src/jit/block.cpp
+++ b/src/jit/block.cpp
@@ -637,3 +637,69 @@ unsigned PtrKeyFuncs<BasicBlock>::GetHashCode(const BasicBlock* ptr)
return ptr->bbNum;
}
+//------------------------------------------------------------------------
+// inlExpLst: default constructor for an inlExpList
+//
+// Notes: use for the root instance. We set ixlCode to nullptr here
+// (rather than the IL buffer address of the root method) to preserve
+// existing behavior, which is to allow one recursive inline.
+
+inlExpLst::inlExpLst() : ixlParent(nullptr), ixlChild(nullptr),
+ ixlSibling(nullptr), ilOffset(BAD_IL_OFFSET),
+ ixlCode(nullptr)
+{
+#ifdef DEBUG
+ methodName = nullptr;
+ depth = 0;
+#endif
+}
+
+
+#ifdef DEBUG
+
+//------------------------------------------------------------------------
+// Dump: Dump an inlExpLst entry and all descendants to stdout
+//
+// Arguments:
+// indent: indentation level for this node
+
+void inlExpLst::Dump(int indent)
+{
+ // Handle fact that siblings are in reverse order.
+ if (ixlSibling != nullptr)
+ {
+ ixlSibling->Dump(indent);
+ }
+
+ // Dump this node
+ if (ixlParent == nullptr)
+ {
+ // root
+ printf("Inlines into %s\n", methodName);
+ }
+ else
+ {
+ for (int i = 0; i < indent; i++)
+ {
+ printf(" ");
+ }
+
+ if (ilOffset == BAD_IL_OFFSET)
+ {
+ printf("[IL=?] %s\n", methodName);
+ }
+ else
+ {
+ IL_OFFSET offset = jitGetILoffs(ilOffset);
+ printf("[IL=%d] %s\n", offset, methodName);
+ }
+ }
+
+ // Recurse to first child
+ if (ixlChild != nullptr)
+ {
+ ixlChild->Dump(indent + 2);
+ }
+}
+#endif
+