Skip to content

Instantly share code, notes, and snippets.

@rednaxelafx
Created August 9, 2011 09:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rednaxelafx/1133678 to your computer and use it in GitHub Desktop.
Save rednaxelafx/1133678 to your computer and use it in GitHub Desktop.
failed attempt to add Phi::exact_type() to HotSpot C1
diff -r 4aa5974a06dd src/share/vm/c1/c1_Instruction.cpp
--- a/src/share/vm/c1/c1_Instruction.cpp Sat Aug 06 08:28:08 2011 -0700
+++ b/src/share/vm/c1/c1_Instruction.cpp Mon Aug 08 23:54:46 2011 +0800
@@ -29,6 +29,7 @@
#include "c1/c1_ValueStack.hpp"
#include "ci/ciObjArrayKlass.hpp"
#include "ci/ciTypeArrayKlass.hpp"
+#include "utilities/stack.inline.hpp"
// Implementation of Instruction
@@ -135,6 +136,59 @@
}
+static
+ciType* find_exact_type(const Phi* self, Stack<const Phi*>& visited) {
+ // check cycles
+ StackIterator<const Phi*> iter(visited);
+ while (!iter.is_empty()) {
+ // cycle found, break it
+ if (self == iter.next()) return NULL;
+ }
+
+ visited.push(self);
+
+ ciType* the_type = NULL;
+
+ for (int i = 0; i < self->operand_count(); i++) {
+ Value opd = self->operand_at(i);
+ if (self == opd || opd->as_UnsafeGetRaw() != NULL) continue; // skip over itself and UnsafeGetRaw
+
+ ciType* opd_exact_type;
+ const Phi* opd_phi = opd->as_Phi();
+ if (opd_phi != NULL) {
+ opd_exact_type = find_exact_type(opd_phi, visited);
+ } else {
+ opd_exact_type = opd->exact_type();
+ }
+
+ // if any of the operands that we care doesn't have exact type, give up
+ if (opd_exact_type == NULL) return NULL;
+
+ if (the_type != NULL) {
+ // be conservative here: iff all operands have the same exact type, return that type,
+ // otherwise give up and return null
+ if (!the_type->equals(opd_exact_type)) {
+ the_type = NULL;
+ break;
+ }
+ } else {
+ the_type = opd_exact_type;
+ }
+ }
+
+ visited.pop();
+
+ return the_type;
+}
+
+ciType* Phi::exact_type() const {
+ assert(!is_illegal(), "must be a legal Phi");
+
+ Stack<const Phi*> visited;
+ return find_exact_type(this, visited);
+}
+
+
ciType* Local::exact_type() const {
ciType* type = declared_type();
diff -r 4aa5974a06dd src/share/vm/c1/c1_Instruction.hpp
--- a/src/share/vm/c1/c1_Instruction.hpp Sat Aug 06 08:28:08 2011 -0700
+++ b/src/share/vm/c1/c1_Instruction.hpp Mon Aug 08 23:54:46 2011 +0800
@@ -501,6 +501,7 @@
virtual RoundFP* as_RoundFP() { return NULL; }
virtual ExceptionObject* as_ExceptionObject() { return NULL; }
virtual UnsafeOp* as_UnsafeOp() { return NULL; }
+ virtual UnsafeGetRaw* as_UnsafeGetRaw() { return NULL; }
virtual void visit(InstructionVisitor* v) = 0;
@@ -585,6 +586,8 @@
cannot_simplify = 1 << 1
};
+ ciType* exact_type() const;
+
// accessors
bool is_local() const { return _index >= 0; }
bool is_on_stack() const { return !is_local(); }
CompilerOracle: compileonly WrongInline.test
VM option '+PrintCompilation'
VM option '+PrintInlining'
VM option '+PrintIRDuringConstruction'
VM option '+PrintPhiFunctions'
VM option 'CompileThreshold=2'
CompilerOracle: compileonly java/util*.*
690 89 WrongInline::test (64 bytes)
********** try_merge for block B0
no existing state for block B0
-----------------------------------
new state for block B0
static void WrongInline.test(jobject)empty stack
local 0 a7 local[index 0]
local 1 null
local 2 null
local 3 null
===================================
first call of try_merge for this block
********** try_merge for block B0 successful
B0 (SV) [0, -1] sux: B1 B2
empty stack
inlining depth 0
__bci__use__tid____instr____________________________________
locals size: 4 stack size: 0
. 1 0 i8 a7.length
2 0 i9 2
. 3 0 i10 i8 % i9
4 0 i11 0
. 4 0 12 if i10 != i11 then B2 else B1
********** try_merge for block B1
no existing state for block B1
-----------------------------------
new state for block B1
static void WrongInline.test(jobject)empty stack
local 0 a7 local[index 0]
local 1 null
local 2 null
local 3 null
===================================
first call of try_merge for this block
invalidating dead local 0
********** try_merge for block B1 successful
********** try_merge for block B2
no existing state for block B2
-----------------------------------
new state for block B2
static void WrongInline.test(jobject)empty stack
local 0 a7 local[index 0]
local 1 null
local 2 null
local 3 null
===================================
first call of try_merge for this block
invalidating dead local 0
********** try_merge for block B2 successful
B1 (V) [7, -1] sux: B3 pred: B0
empty stack
inlining depth 0
__bci__use__tid____instr____________________________________
locals size: 4 stack size: 0
. 7 0 a13 new instance java/util/ArrayList
@ 11 java.util.ArrayList::<init> (7 bytes)
B1 (V) [7, -1] sux: B3 pred: B0
empty stack
inlining depth 0
__bci__use__tid____instr____________________________________
locals size: 1 stack size: 0
1 0 i16 10
@ 3 java.util.ArrayList::<init> (44 bytes) callee is too large
. 3 0 v17 a13.invokespecial(i16)
java/util/ArrayList.<init>(I)V
. 14 0 18 goto B7
********** try_merge for block B7
no existing state for block B7
-----------------------------------
new state for block B7
static void WrongInline.test(jobject) 1 a13 new instance java/util/ArrayList
local 0 null
local 1 null
local 2 null
local 3 null
===================================
first call of try_merge for this block
********** try_merge for block B7 successful
. 15 0 19 goto B3
********** try_merge for block B3
no existing state for block B3
-----------------------------------
new state for block B3
static void WrongInline.test(jobject)empty stack
local 0 null
local 1 a13 new instance java/util/ArrayList
local 2 null
local 3 null
===================================
first call of try_merge for this block
********** try_merge for block B3 successful
B2 (V) [18, -1] sux: B3 pred: B0
empty stack
inlining depth 0
__bci__use__tid____instr____________________________________
locals size: 4 stack size: 0
. 18 0 a20 new instance java/util/ArrayList
22 0 i21 20
@ 24 java.util.ArrayList::<init> (44 bytes) callee is too large
. 24 0 v22 a20.invokespecial(i21)
java/util/ArrayList.<init>(I)V
. 28 0 23 goto B3
********** try_merge for block B3
existing state for block B3
static void WrongInline.test(jobject)empty stack
local 0 null
local 1 a13 new instance java/util/ArrayList
local 2 null
local 3 null
-----------------------------------
new state for block B3
static void WrongInline.test(jobject)empty stack
local 0 null
local 1 a20 new instance java/util/ArrayList
local 2 null
local 3 null
===================================
exisiting state found
creating phi functions on demand
creating phi-function a24 for local 1
********** try_merge for block B3 successful
B3 (V) [28, -1] sux: B4 pred: B1 B2
empty stack
inlining depth 0
__bci__use__tid____instr____________________________________
locals size: 4 stack size: 0
28 0 i25 0
. 30 0 26 goto B4
********** try_merge for block B4
no existing state for block B4
-----------------------------------
new state for block B4
static void WrongInline.test(jobject)empty stack
local 0 null
local 1 a24 phi function, a13, a20
local 2 i25 0
local 3 null
===================================
first call of try_merge for this block
loop header block, initializing phi functions
creating phi-function a27 for local 1
creating phi-function i28 for local 2
********** try_merge for block B4 successful
B4 (LHV) [30, -1] sux: B5 B6 pred: B3
empty stack
inlining depth 0
__bci__use__tid____instr____________________________________
locals size: 4 stack size: 0
31 0 i29 2
. 32 0 30 if i28 >= i29 then B6 else B5
********** try_merge for block B5
no existing state for block B5
-----------------------------------
new state for block B5
static void WrongInline.test(jobject)empty stack
local 0 null
local 1 a27 phi function, a24
local 2 i28 phi function, i25
local 3 null
===================================
first call of try_merge for this block
********** try_merge for block B5 successful
********** try_merge for block B6
no existing state for block B6
-----------------------------------
new state for block B6
static void WrongInline.test(jobject)empty stack
local 0 null
local 1 a27 phi function, a24
local 2 i28 phi function, i25
local 3 null
===================================
first call of try_merge for this block
invalidating dead local 1
invalidating dead local 2
********** try_merge for block B6 successful
B5 (V) [35, -1] sux: B4 pred: B4
empty stack
inlining depth 0
__bci__use__tid____instr____________________________________
locals size: 4 stack size: 0
@ 36 java.util.ArrayList::size (5 bytes)
. 36 0 a31 null_check(a27)
B5 (V) [35, -1] sux: B4 pred: B4
empty stack
inlining depth 0
__bci__use__tid____instr____________________________________
locals size: 1 stack size: 0
. 1 0 i34 a27._12 (I)
. 41 0 35 goto B9
********** try_merge for block B9
no existing state for block B9
-----------------------------------
new state for block B9
static void WrongInline.test(jobject) 1 i34 a27._12 (I)
local 0 null
local 1 a27 phi function, a24
local 2 i28 phi function, i25
local 3 null
===================================
first call of try_merge for this block
invalidating dead local 1
********** try_merge for block B9 successful
42 0 a36 <instance 0x09d5e360>
. 42 0 a37 a36._108 (L)
!m @ 46 java.io.PrintStream::println (24 bytes) excluded by CompilerOracle
. 46 0 a38 null_check(a37)
. 46 0 v39 a37.invokespecial(i34)
java/io/PrintStream.println(I)V
. 49 0 a40 new instance java/util/LinkedList
@ 53 java.util.LinkedList::<init> (10 bytes)
B5 (V) [35, 41] -> B9 sux: B9 pred: B4
empty stack
inlining depth 0
__bci__use__tid____instr____________________________________
locals size: 1 stack size: 0
@ 1 java.util.AbstractSequentialList::<init> (5 bytes)
B5 (V) [35, 41] -> B9 sux: B9 pred: B4
empty stack
inlining depth 0
__bci__use__tid____instr____________________________________
locals size: 1 stack size: 0
@ 1 java.util.AbstractList::<init> (10 bytes)
B5 (V) [35, 41] -> B9 sux: B9 pred: B4
empty stack
inlining depth 0
__bci__use__tid____instr____________________________________
locals size: 1 stack size: 0
@ 1 java.util.AbstractCollection::<init> (5 bytes)
B5 (V) [35, 41] -> B9 sux: B9 pred: B4
empty stack
inlining depth 0
__bci__use__tid____instr____________________________________
locals size: 1 stack size: 0
@ 1 java.lang.Object::<init> (1 bytes) excluded by CompilerOracle
. 1 0 v49 a40.invokespecial()
java/lang/Object.<init>()V
. 4 0 50 goto B17
********** try_merge for block B17
no existing state for block B17
-----------------------------------
new state for block B17
virtual void java.util.AbstractList.<init>()empty stack
local 0 a40 new instance java/util/LinkedList
virtual void java.util.AbstractSequentialList.<init>()empty stack
local 0 a40 new instance java/util/LinkedList
virtual void java.util.LinkedList.<init>()empty stack
local 0 a40 new instance java/util/LinkedList
static void WrongInline.test(jobject) 1 a40 new instance java/util/LinkedList
local 0 null
local 1 a27 phi function, a24
local 2 i28 phi function, i25
local 3 i34 a27._12 (I)
===================================
first call of try_merge for this block
********** try_merge for block B17 successful
5 0 i51 0
. 6 0 i52 a40._8 := i51 (I)
. 4 0 53 goto B15
********** try_merge for block B15
no existing state for block B15
-----------------------------------
new state for block B15
virtual void java.util.AbstractSequentialList.<init>()empty stack
local 0 a40 new instance java/util/LinkedList
virtual void java.util.LinkedList.<init>()empty stack
local 0 a40 new instance java/util/LinkedList
static void WrongInline.test(jobject) 1 a40 new instance java/util/LinkedList
local 0 null
local 1 a27 phi function, a24
local 2 i28 phi function, i25
local 3 i34 a27._12 (I)
===================================
first call of try_merge for this block
invalidating dead local 0
********** try_merge for block B15 successful
. 4 0 54 goto B13
********** try_merge for block B13
no existing state for block B13
-----------------------------------
new state for block B13
virtual void java.util.LinkedList.<init>()empty stack
local 0 a40 new instance java/util/LinkedList
static void WrongInline.test(jobject) 1 a40 new instance java/util/LinkedList
local 0 null
local 1 a27 phi function, a24
local 2 i28 phi function, i25
local 3 i34 a27._12 (I)
===================================
first call of try_merge for this block
********** try_merge for block B13 successful
. 6 0 i56 a40._12 := i51 (I)
. 56 0 57 goto B11
********** try_merge for block B11
no existing state for block B11
-----------------------------------
new state for block B11
static void WrongInline.test(jobject) 1 a40 new instance java/util/LinkedList
local 0 null
local 1 a27 phi function, a24
local 2 i28 phi function, i25
local 3 i34 a27._12 (I)
===================================
first call of try_merge for this block
invalidating dead local 1
invalidating dead local 3
********** try_merge for block B11 successful
57 0 i58 1
57 0 i59 i28 + i58
. 60 0 60 goto B4 (safepoint)
********** try_merge for block B4
existing state for block B4
static void WrongInline.test(jobject)empty stack
local 0 null
local 1 a27 phi function, a24, a40
local 2 i28 phi function, i25, i59
local 3 null
-----------------------------------
new state for block B4
static void WrongInline.test(jobject)empty stack
local 0 null
local 1 a40 new instance java/util/LinkedList
local 2 i59 i28 + i58
local 3 i34 a27._12 (I)
===================================
exisiting state found
loop header block, phis must be present
********** try_merge for block B4 successful
B6 (V) [63, -1] pred: B4
empty stack
inlining depth 0
__bci__use__tid____instr____________________________________
locals size: 4 stack size: 0
. 63 0 v61 return
702 90 java.util.LinkedList::size (5 bytes)
********** try_merge for block B0
no existing state for block B0
-----------------------------------
new state for block B0
virtual jint java.util.LinkedList.size()empty stack
local 0 a1 local[index 0]
===================================
first call of try_merge for this block
********** try_merge for block B0 successful
B0 (SV) [0, -1]
empty stack
inlining depth 0
__bci__use__tid____instr____________________________________
locals size: 1 stack size: 0
. 1 0 i2 a1._12 (I)
. 4 0 i3 ireturn i2
import java.util.*;
/*
*/
public class WrongInline {
public static void test(String[] args) {
List<?> list;
if (args.length % 2 == 0) {
list = new ArrayList<String>(); // list1
} else {
list = new ArrayList<String>(32); // list2
}
// list3 = Phi(list1, list2)
for (int i = 0; i < 2; i++) {
// list4 = Phi(list3, list5)
int size = list.size(); // will incorrectly inline ArrayList::size() here
System.out.println(size);
list = new LinkedList<String>(); // list5
}
}
public static void main(String[] args) throws Exception {
test(args);
test(args);
test(args);
System.in.read();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment