mirror of
https://github.com/openjdk/jdk.git
synced 2026-01-28 03:58:21 +00:00
Compare commits
3 Commits
ff22857609
...
0ef73ef943
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0ef73ef943 | ||
|
|
b79738c365 | ||
|
|
b028198173 |
@ -281,8 +281,7 @@ macro(OpaqueLoopInit)
|
||||
macro(OpaqueLoopStride)
|
||||
macro(OpaqueMultiversioning)
|
||||
macro(OpaqueZeroTripGuard)
|
||||
macro(OpaqueNotNull)
|
||||
macro(OpaqueGuard)
|
||||
macro(OpaqueCheck)
|
||||
macro(OpaqueInitializedAssertionPredicate)
|
||||
macro(OpaqueTemplateAssertionPredicate)
|
||||
macro(ProfileBoolean)
|
||||
|
||||
@ -588,7 +588,7 @@ bool ConnectionGraph::can_reduce_check_users(Node* n, uint nesting) const {
|
||||
// CmpP/N used by the If controlling the cast.
|
||||
if (use->in(0)->is_IfTrue() || use->in(0)->is_IfFalse()) {
|
||||
Node* iff = use->in(0)->in(0);
|
||||
// We may have an OpaqueNotNull node between If and Bool nodes. But we could also have a sub class of IfNode,
|
||||
// We may have an OpaqueCheck node between If and Bool nodes. But we could also have a sub class of IfNode,
|
||||
// for example, an OuterStripMinedLoopEnd or a Parse Predicate. Bail out in all these cases.
|
||||
bool can_reduce = (iff->Opcode() == Op_If) && iff->in(1)->is_Bool() && iff->in(1)->in(1)->is_Cmp();
|
||||
if (can_reduce) {
|
||||
|
||||
@ -1472,7 +1472,7 @@ Node* GraphKit::cast_not_null(Node* obj, bool do_replace_in_map) {
|
||||
// In that case that data path will die and we need the control path
|
||||
// to become dead as well to keep the graph consistent. So we have to
|
||||
// add a check for null for which one branch can't be taken. It uses
|
||||
// an OpaqueNotNull node that will cause the check to be removed after loop
|
||||
// an OpaqueCheck node that will cause the check to be removed after loop
|
||||
// opts so the test goes away and the compiled code doesn't execute a
|
||||
// useless check.
|
||||
Node* GraphKit::must_be_not_null(Node* value, bool do_replace_in_map) {
|
||||
@ -1481,7 +1481,7 @@ Node* GraphKit::must_be_not_null(Node* value, bool do_replace_in_map) {
|
||||
}
|
||||
Node* chk = _gvn.transform(new CmpPNode(value, null()));
|
||||
Node* tst = _gvn.transform(new BoolNode(chk, BoolTest::ne));
|
||||
Node* opaq = _gvn.transform(new OpaqueNotNullNode(C, tst));
|
||||
Node* opaq = _gvn.transform(new OpaqueCheckNode(C, tst, true));
|
||||
IfNode* iff = new IfNode(control(), opaq, PROB_MAX, COUNT_UNKNOWN);
|
||||
_gvn.set_type(iff, iff->Value(&_gvn));
|
||||
if (!tst->is_Con()) {
|
||||
|
||||
@ -899,7 +899,7 @@ inline Node* LibraryCallKit::generate_negative_guard(Node* index, RegionNode* re
|
||||
Node* cmp_lt = _gvn.transform(new CmpINode(index, intcon(0)));
|
||||
Node* bol_lt = _gvn.transform(new BoolNode(cmp_lt, BoolTest::lt));
|
||||
if (is_opaque) {
|
||||
bol_lt = _gvn.transform(new OpaqueGuardNode(C, bol_lt));
|
||||
bol_lt = _gvn.transform(new OpaqueCheckNode(C, bol_lt, false));
|
||||
}
|
||||
Node* is_neg = generate_guard(bol_lt, region, PROB_MIN);
|
||||
if (is_neg != nullptr && pos_index != nullptr) {
|
||||
@ -940,7 +940,7 @@ inline Node* LibraryCallKit::generate_limit_guard(Node* offset,
|
||||
Node* cmp_lt = _gvn.transform(new CmpUNode(array_length, last));
|
||||
Node* bol_lt = _gvn.transform(new BoolNode(cmp_lt, BoolTest::lt));
|
||||
if (is_opaque) {
|
||||
bol_lt = _gvn.transform(new OpaqueGuardNode(C, bol_lt));
|
||||
bol_lt = _gvn.transform(new OpaqueCheckNode(C, bol_lt, false));
|
||||
}
|
||||
Node* is_over = generate_guard(bol_lt, region, PROB_MIN);
|
||||
return is_over;
|
||||
|
||||
@ -158,7 +158,7 @@ class LibraryCallKit : public GraphKit {
|
||||
Node* generate_fair_guard(Node* test, RegionNode* region);
|
||||
Node* generate_negative_guard(Node* index, RegionNode* region,
|
||||
// resulting CastII of index:
|
||||
Node* *pos_index = nullptr,
|
||||
Node** pos_index = nullptr,
|
||||
bool is_opaque = false);
|
||||
Node* generate_limit_guard(Node* offset, Node* subseq_length,
|
||||
Node* array_length,
|
||||
|
||||
@ -1234,8 +1234,7 @@ bool IdealLoopTree::policy_range_check(PhaseIdealLoop* phase, bool provisional,
|
||||
continue;
|
||||
}
|
||||
if (!bol->is_Bool()) {
|
||||
assert(bol->is_OpaqueNotNull() ||
|
||||
bol->is_OpaqueGuard() ||
|
||||
assert(bol->is_OpaqueCheck() ||
|
||||
bol->is_OpaqueTemplateAssertionPredicate() ||
|
||||
bol->is_OpaqueInitializedAssertionPredicate() ||
|
||||
bol->is_OpaqueMultiversioning(),
|
||||
|
||||
@ -1704,8 +1704,7 @@ void PhaseIdealLoop::try_sink_out_of_loop(Node* n) {
|
||||
!n->is_Proj() &&
|
||||
!n->is_MergeMem() &&
|
||||
!n->is_CMove() &&
|
||||
!n->is_OpaqueNotNull() &&
|
||||
!n->is_OpaqueGuard() &&
|
||||
!n->is_OpaqueCheck() &&
|
||||
!n->is_OpaqueInitializedAssertionPredicate() &&
|
||||
!n->is_OpaqueTemplateAssertionPredicate() &&
|
||||
!is_raw_to_oop_cast && // don't extend live ranges of raw oops
|
||||
@ -2046,14 +2045,14 @@ Node* PhaseIdealLoop::clone_iff(PhiNode* phi) {
|
||||
if (b->is_Phi()) {
|
||||
_igvn.replace_input_of(phi, i, clone_iff(b->as_Phi()));
|
||||
} else {
|
||||
assert(b->is_Bool() || b->is_OpaqueNotNull() || b->is_OpaqueGuard() || b->is_OpaqueInitializedAssertionPredicate(),
|
||||
"bool, non-null check with OpaqueNotNull or Initialized Assertion Predicate with its Opaque node");
|
||||
assert(b->is_Bool() || b->is_OpaqueCheck() || b->is_OpaqueInitializedAssertionPredicate(),
|
||||
"bool, non-null check with OpaqueCheck or Initialized Assertion Predicate with its Opaque node");
|
||||
}
|
||||
}
|
||||
Node* n = phi->in(1);
|
||||
Node* sample_opaque = nullptr;
|
||||
Node *sample_bool = nullptr;
|
||||
if (n->is_OpaqueNotNull() || n->is_OpaqueInitializedAssertionPredicate() || n->is_OpaqueGuard()) {
|
||||
if (n->is_OpaqueCheck() || n->is_OpaqueInitializedAssertionPredicate()) {
|
||||
sample_opaque = n;
|
||||
sample_bool = n->in(1);
|
||||
assert(sample_bool->is_Bool(), "wrong type");
|
||||
@ -2229,7 +2228,7 @@ void PhaseIdealLoop::clone_loop_handle_data_uses(Node* old, Node_List &old_new,
|
||||
// split if to break.
|
||||
assert(!use->is_OpaqueTemplateAssertionPredicate(),
|
||||
"should not clone a Template Assertion Predicate which should be removed once it's useless");
|
||||
if (use->is_If() || use->is_CMove() || use->is_OpaqueGuard() || use->is_OpaqueNotNull() || use->is_OpaqueInitializedAssertionPredicate() ||
|
||||
if (use->is_If() || use->is_CMove() || use->is_OpaqueCheck() || use->is_OpaqueInitializedAssertionPredicate() ||
|
||||
(use->Opcode() == Op_AllocateArray && use->in(AllocateNode::ValidLengthTest) == old)) {
|
||||
// Since this code is highly unlikely, we lazily build the worklist
|
||||
// of such Nodes to go split.
|
||||
|
||||
@ -2500,8 +2500,7 @@ void PhaseMacroExpand::eliminate_macro_nodes() {
|
||||
assert(n->Opcode() == Op_LoopLimit ||
|
||||
n->Opcode() == Op_ModD ||
|
||||
n->Opcode() == Op_ModF ||
|
||||
n->is_OpaqueNotNull() ||
|
||||
n->is_OpaqueGuard() ||
|
||||
n->is_OpaqueCheck() ||
|
||||
n->is_OpaqueInitializedAssertionPredicate() ||
|
||||
n->Opcode() == Op_MaxL ||
|
||||
n->Opcode() == Op_MinL ||
|
||||
@ -2549,24 +2548,15 @@ void PhaseMacroExpand::eliminate_opaque_looplimit_macro_nodes() {
|
||||
} else if (n->is_Opaque1()) {
|
||||
_igvn.replace_node(n, n->in(1));
|
||||
success = true;
|
||||
} else if (n->is_OpaqueNotNull()) {
|
||||
// Tests with OpaqueNotNull nodes are implicitly known to be true. Replace the node with true. In debug builds,
|
||||
} else if (n->is_OpaqueCheck()) {
|
||||
// Tests with OpaqueCheck nodes are implicitly known. Replace the node with true/false. In debug builds,
|
||||
// we leave the test in the graph to have an additional sanity check at runtime. If the test fails (i.e. a bug),
|
||||
// we will execute a Halt node.
|
||||
#ifdef ASSERT
|
||||
_igvn.replace_node(n, n->in(1));
|
||||
#else
|
||||
_igvn.replace_node(n, _igvn.intcon(1));
|
||||
#endif
|
||||
success = true;
|
||||
} else if (n->is_OpaqueGuard()) {
|
||||
// Tests with OpaqueGuard nodes are implicitly known to be false. Replace the node with false. In debug
|
||||
// builds, we leave the test in the graph to have an additional sanity check at runtime. If the test
|
||||
// fails (i.e. a bug), we will execute a Halt node.
|
||||
#ifdef ASSERT
|
||||
_igvn.replace_node(n, n->in(1));
|
||||
#else
|
||||
_igvn.replace_node(n, _igvn.intcon(0));
|
||||
bool is_positive = n->as_OpaqueCheck()->is_positive();
|
||||
_igvn.replace_node(n, _igvn.intcon(is_positive?1:0));
|
||||
#endif
|
||||
success = true;
|
||||
} else if (n->is_OpaqueInitializedAssertionPredicate()) {
|
||||
|
||||
@ -142,8 +142,7 @@ class Opaque1Node;
|
||||
class OpaqueLoopInitNode;
|
||||
class OpaqueLoopStrideNode;
|
||||
class OpaqueMultiversioningNode;
|
||||
class OpaqueNotNullNode;
|
||||
class OpaqueGuardNode;
|
||||
class OpaqueCheckNode;
|
||||
class OpaqueInitializedAssertionPredicateNode;
|
||||
class OpaqueTemplateAssertionPredicateNode;
|
||||
class OuterStripMinedLoopNode;
|
||||
@ -817,13 +816,12 @@ public:
|
||||
DEFINE_CLASS_ID(OpaqueLoopInit, Opaque1, 0)
|
||||
DEFINE_CLASS_ID(OpaqueLoopStride, Opaque1, 1)
|
||||
DEFINE_CLASS_ID(OpaqueMultiversioning, Opaque1, 2)
|
||||
DEFINE_CLASS_ID(OpaqueNotNull, Node, 17)
|
||||
DEFINE_CLASS_ID(OpaqueCheck, Node, 17)
|
||||
DEFINE_CLASS_ID(OpaqueInitializedAssertionPredicate, Node, 18)
|
||||
DEFINE_CLASS_ID(OpaqueTemplateAssertionPredicate, Node, 19)
|
||||
DEFINE_CLASS_ID(Move, Node, 20)
|
||||
DEFINE_CLASS_ID(LShift, Node, 21)
|
||||
DEFINE_CLASS_ID(Neg, Node, 22)
|
||||
DEFINE_CLASS_ID(OpaqueGuard, Node, 23)
|
||||
|
||||
_max_classes = ClassMask_Neg
|
||||
};
|
||||
@ -998,8 +996,7 @@ public:
|
||||
DEFINE_CLASS_QUERY(NegV)
|
||||
DEFINE_CLASS_QUERY(NeverBranch)
|
||||
DEFINE_CLASS_QUERY(Opaque1)
|
||||
DEFINE_CLASS_QUERY(OpaqueNotNull)
|
||||
DEFINE_CLASS_QUERY(OpaqueGuard)
|
||||
DEFINE_CLASS_QUERY(OpaqueCheck)
|
||||
DEFINE_CLASS_QUERY(OpaqueInitializedAssertionPredicate)
|
||||
DEFINE_CLASS_QUERY(OpaqueTemplateAssertionPredicate)
|
||||
DEFINE_CLASS_QUERY(OpaqueLoopInit)
|
||||
|
||||
@ -108,11 +108,7 @@ void OpaqueMultiversioningNode::dump_spec(outputStream *st) const {
|
||||
}
|
||||
#endif
|
||||
|
||||
const Type* OpaqueNotNullNode::Value(PhaseGVN* phase) const {
|
||||
return phase->type(in(1));
|
||||
}
|
||||
|
||||
const Type* OpaqueGuardNode::Value(PhaseGVN* phase) const {
|
||||
const Type* OpaqueCheckNode::Value(PhaseGVN* phase) const {
|
||||
return phase->type(in(1));
|
||||
}
|
||||
|
||||
|
||||
@ -130,37 +130,25 @@ public:
|
||||
// This node is used in the context of intrinsics. We sometimes implicitly know that an object is non-null even though
|
||||
// the compiler cannot prove it. We therefore add a corresponding cast to propagate this implicit knowledge. However,
|
||||
// this cast could become top during optimizations (input to cast becomes null) and the data path is folded. To ensure
|
||||
// that the control path is also properly folded, we insert an If node with a OpaqueNotNullNode as condition. During
|
||||
// macro expansion, we replace the OpaqueNotNullNodes with true in product builds such that the actually unneeded checks
|
||||
// that the control path is also properly folded, we insert an If node with a OpaqueCheckNode as condition. During
|
||||
// macro expansion, we replace the OpaqueCheckNodes with true in product builds such that the actually unneeded checks
|
||||
// are folded and do not end up in the emitted code. In debug builds, we keep the actual checks as additional
|
||||
// verification code (i.e. removing OpaqueNotNullNodes and use the BoolNode inputs instead). For more details, also see
|
||||
// verification code (i.e. removing OpaqueCheckNodes and use the BoolNode inputs instead). For more details, also see
|
||||
// GraphKit::must_be_not_null().
|
||||
class OpaqueNotNullNode : public Node {
|
||||
// Similarly, sometimes we know that a size or limit guard is checked (e.g. there is already a guard in the caller) but
|
||||
// the compiler cannot prove it. We could in principle avoid adding a guard in the intrinsic but in some cases (e.g.
|
||||
// when the input is a constant that breaks the guard and the caller guard is not inlined) the input of the intrinsic
|
||||
// can become top and the data path is folded. To ensure that the control path is also properly folded, we insert an
|
||||
// OpaqueCheckNode before the If node in the guard. During macro expansion, we replace the OpaqueCheckNode with false
|
||||
// in product builds such that the actually unneeded guards are folded and do not end up in the emitted code. In debug
|
||||
// builds, we keep the actual checks as additional verification code (i.e. removing OpaqueCheckNodes and use the
|
||||
// BoolNode inputs instead).
|
||||
class OpaqueCheckNode : public Node {
|
||||
private:
|
||||
bool _positive;
|
||||
public:
|
||||
OpaqueNotNullNode(Compile* C, Node* tst) : Node(nullptr, tst) {
|
||||
init_class_id(Class_OpaqueNotNull);
|
||||
init_flags(Flag_is_macro);
|
||||
C->add_macro_node(this);
|
||||
}
|
||||
|
||||
virtual int Opcode() const;
|
||||
virtual const Type* Value(PhaseGVN* phase) const;
|
||||
virtual const Type* bottom_type() const { return TypeInt::BOOL; }
|
||||
};
|
||||
|
||||
// Similar to OpaqueNotNullNode but for guards. Sometimes we know that a size or limit guard is checked
|
||||
// (e.g. there is already a guard in the caller) but the compiler cannot prove it. We could in principle avoid
|
||||
// adding a guard in the intrinsic but in some cases (e.g. when the input is a constant that breaks the guard
|
||||
// and the caller guard is not inlined) the input of the intrinsic can become top and the data path is folded.
|
||||
// Similar to OpaqueNotNullNode to ensure that the control path is also properly folded, we insert a OpaqueGuardNode
|
||||
// before the If node in the guard. During macro expansion, we replace the OpaqueGuardNode with false in product
|
||||
// builds such that the actually unneeded guards are folded and do not end up in the emitted code. In debug builds,
|
||||
// we keep the actual checks as additional verification code (i.e. removing OpaqueGuardNode and use the BoolNode
|
||||
// inputs instead).
|
||||
class OpaqueGuardNode : public Node {
|
||||
public:
|
||||
OpaqueGuardNode(Compile* C, Node* tst) : Node(nullptr, tst) {
|
||||
init_class_id(Class_OpaqueGuard);
|
||||
OpaqueCheckNode(Compile* C, Node* tst, bool positive) : Node(nullptr, tst), _positive(positive) {
|
||||
init_class_id(Class_OpaqueCheck);
|
||||
init_flags(Flag_is_macro);
|
||||
C->add_macro_node(this);
|
||||
}
|
||||
@ -168,6 +156,7 @@ class OpaqueGuardNode : public Node {
|
||||
virtual int Opcode() const;
|
||||
virtual const Type* Value(PhaseGVN* phase) const;
|
||||
virtual const Type* bottom_type() const { return TypeInt::BOOL; }
|
||||
bool is_positive() { return _positive; }
|
||||
};
|
||||
|
||||
// This node is used for Template Assertion Predicate BoolNodes. A Template Assertion Predicate is always removed
|
||||
|
||||
@ -307,7 +307,7 @@ bool PhaseIdealLoop::clone_cmp_down(Node* n, const Node* blk1, const Node* blk2)
|
||||
assert( bol->is_Bool(), "" );
|
||||
if (bol->outcnt() == 1) {
|
||||
Node* use = bol->unique_out();
|
||||
if (use->is_OpaqueNotNull() || use->is_OpaqueGuard() || use->is_OpaqueTemplateAssertionPredicate() ||
|
||||
if (use->is_OpaqueCheck() || use->is_OpaqueTemplateAssertionPredicate() ||
|
||||
use->is_OpaqueInitializedAssertionPredicate()) {
|
||||
if (use->outcnt() == 1) {
|
||||
Node* iff = use->unique_out();
|
||||
@ -331,8 +331,8 @@ bool PhaseIdealLoop::clone_cmp_down(Node* n, const Node* blk1, const Node* blk2)
|
||||
// Recursively sink any BoolNode
|
||||
for (DUIterator j = bol->outs(); bol->has_out(j); j++) {
|
||||
Node* u = bol->out(j);
|
||||
// Uses are either IfNodes, CMoves, OpaqueNotNull, OpaqueGuard or Opaque*AssertionPredicate
|
||||
if (u->is_OpaqueNotNull() || u->is_OpaqueGuard() || u->is_OpaqueTemplateAssertionPredicate() ||
|
||||
// Uses are either IfNodes, CMoves, OpaqueCheck or Opaque*AssertionPredicate
|
||||
if (u->is_OpaqueCheck() || u->is_OpaqueTemplateAssertionPredicate() ||
|
||||
u->is_OpaqueInitializedAssertionPredicate()) {
|
||||
assert(u->in(1) == bol, "bad input");
|
||||
for (DUIterator_Last kmin, k = u->last_outs(kmin); k >= kmin; --k) {
|
||||
|
||||
@ -64,7 +64,7 @@ public class TestCanReduceCheckUsersDifferentIfs {
|
||||
// (6) CastPP(phi1) ends up at IfFalse of OuterStripMinedLoopEnd of loop (L).
|
||||
// (7) EA tries to reduce phi1(CheckCastPP(B), CheckCastPP(c)) and looks at
|
||||
// OuterStripMinedLoopEnd and asserts that if it's not an IfNode that it has
|
||||
// an OpaqueNotNull which obviously is not the case and the assert fails.
|
||||
// an OpaqueCheck which obviously is not the case and the assert fails.
|
||||
|
||||
// (5) Found to be false after PhaseIdealLoop before EA and is folded away.
|
||||
if (y == 76) {
|
||||
@ -77,7 +77,7 @@ public class TestCanReduceCheckUsersDifferentIfs {
|
||||
}
|
||||
|
||||
// Same as testOuterStripMinedLoopEnd() but we find in (7) a ParsePredicate from the
|
||||
// removed loop (L) which also does not have an OpaqueNotNull and the assert fails.
|
||||
// removed loop (L) which also does not have an OpaqueCheck and the assert fails.
|
||||
static void testParsePredicate() {
|
||||
A a = flag ? new B() : new C();
|
||||
|
||||
|
||||
@ -33,7 +33,7 @@ package compiler.intrinsics.string;
|
||||
|
||||
import compiler.lib.ir_framework.*;
|
||||
|
||||
public class TestOpaqueGuardNodes {
|
||||
public class TestOpaqueCheckNodes {
|
||||
|
||||
static byte[] bytes = new byte[42];
|
||||
|
||||
@ -49,8 +49,8 @@ public class TestOpaqueGuardNodes {
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = {IRNode.OPAQUE_GUARD, "3"}, phase = CompilePhase.AFTER_PARSING)
|
||||
@IR(failOn = {IRNode.OPAQUE_GUARD}, phase = CompilePhase.AFTER_MACRO_EXPANSION)
|
||||
@IR(counts = {IRNode.OPAQUE_CHECK, "3"}, phase = CompilePhase.AFTER_PARSING)
|
||||
@IR(failOn = {IRNode.OPAQUE_CHECK}, phase = CompilePhase.AFTER_MACRO_EXPANSION)
|
||||
@Arguments(setup = "setup")
|
||||
private static String test(byte[] bytes, int i, int l) {
|
||||
return new String(bytes, i , l);
|
||||
@ -3137,9 +3137,9 @@ public class IRNode {
|
||||
machOnlyNameRegex(REPLICATE_HF_IMM8, "replicateHF_imm8_gt128b");
|
||||
}
|
||||
|
||||
public static final String OPAQUE_GUARD = PREFIX + "OPAQUE_GUARD" + POSTFIX;
|
||||
public static final String OPAQUE_CHECK = PREFIX + "OPAQUE_CHECK" + POSTFIX;
|
||||
static {
|
||||
beforeMatchingNameRegex(OPAQUE_GUARD, "OpaqueGuard");
|
||||
beforeMatchingNameRegex(OPAQUE_CHECK, "OpaqueCheck");
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@ -65,15 +65,15 @@ public class OpaqueAccesses {
|
||||
// Finish the line after the node type, skips full line, and eats until before the node types
|
||||
private static final String SKIP = IRNode.MID + IRNode.END + "\\R" + FULL_LINES + "\\s*" + IRNode.START;
|
||||
|
||||
private static final String CALL_STATIC_JAVA_AND_THEN_OPAQUE_NOT_NULL = IRNode.START + "CallStaticJava" + SKIP + "OpaqueNotNull" + IRNode.MID + IRNode.END;
|
||||
private static final String OPAQUE_NOT_NULL_AND_THEN_CALL_STATIC_JAVA = IRNode.START + "OpaqueNotNull" + SKIP + "CallStaticJava" + IRNode.MID + IRNode.END;
|
||||
/* Having both CallStaticJava and OpaqueNotNull, in any order. We use that in a failOn to make sure we have one
|
||||
private static final String CALL_STATIC_JAVA_AND_THEN_OPAQUE_CHECK = IRNode.START + "CallStaticJava" + SKIP + "OpaqueCheck" + IRNode.MID + IRNode.END;
|
||||
private static final String OPAQUE_CHECK_AND_THEN_CALL_STATIC_JAVA = IRNode.START + "OpaqueCheck" + SKIP + "CallStaticJava" + IRNode.MID + IRNode.END;
|
||||
/* Having both CallStaticJava and OpaqueCheck, in any order. We use that in a failOn to make sure we have one
|
||||
* or the other (or none), but not both.
|
||||
* The CallStaticJava happens when the call is not intrinsified, and the OpaqueNotNull comes from the intrinsic.
|
||||
* The CallStaticJava happens when the call is not intrinsified, and the OpaqueCheck comes from the intrinsic.
|
||||
* We don't want a unfinished intrinsic, with the call nevertheless.
|
||||
*/
|
||||
private static final String BOTH_CALL_STATIC_JAVA_AND_OPAQUE_NOT_NULL =
|
||||
"(" + CALL_STATIC_JAVA_AND_THEN_OPAQUE_NOT_NULL + ") | (" + OPAQUE_NOT_NULL_AND_THEN_CALL_STATIC_JAVA + ")";
|
||||
"(" + CALL_STATIC_JAVA_AND_THEN_OPAQUE_CHECK + ") | (" + OPAQUE_CHECK_AND_THEN_CALL_STATIC_JAVA + ")";
|
||||
|
||||
|
||||
@Test
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user