aboutsummaryrefslogtreecommitdiff
path: root/src/share/vm/opto
diff options
context:
space:
mode:
authortwisti <none@none>2009-03-13 11:35:17 -0700
committertwisti <none@none>2009-03-13 11:35:17 -0700
commit871c0d8c64b2d4ea15912fbad9e72612c9bb9028 (patch)
treef6a3cd9172d2246e93893b294ce09f0195e0af94 /src/share/vm/opto
parent0503b54b4c2093d163af18909a11942abfa096ab (diff)
downloadjdk8u_hotspot-871c0d8c64b2d4ea15912fbad9e72612c9bb9028.tar.gz
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
Summary: bitCount() should use POPC on SPARC processors where POPC is implemented directly in hardware. Reviewed-by: kvn, never
Diffstat (limited to 'src/share/vm/opto')
-rw-r--r--src/share/vm/opto/classes.hpp2
-rw-r--r--src/share/vm/opto/connode.hpp22
-rw-r--r--src/share/vm/opto/library_call.cpp33
3 files changed, 55 insertions, 2 deletions
diff --git a/src/share/vm/opto/classes.hpp b/src/share/vm/opto/classes.hpp
index d527f5ea4..87adb737c 100644
--- a/src/share/vm/opto/classes.hpp
+++ b/src/share/vm/opto/classes.hpp
@@ -184,6 +184,8 @@ macro(PCTable)
macro(Parm)
macro(PartialSubtypeCheck)
macro(Phi)
+macro(PopCountI)
+macro(PopCountL)
macro(PowD)
macro(PrefetchRead)
macro(PrefetchWrite)
diff --git a/src/share/vm/opto/connode.hpp b/src/share/vm/opto/connode.hpp
index a16d7f2ee..4c078d1b0 100644
--- a/src/share/vm/opto/connode.hpp
+++ b/src/share/vm/opto/connode.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -635,3 +635,23 @@ class MoveD2LNode : public Node {
virtual uint ideal_reg() const { return Op_RegL; }
virtual const Type* Value( PhaseTransform *phase ) const;
};
+
+//---------- PopCountINode -----------------------------------------------------
+// Population count (bit count) of an integer.
+class PopCountINode : public Node {
+public:
+ PopCountINode(Node* in1) : Node(0, in1) {}
+ virtual int Opcode() const;
+ const Type* bottom_type() const { return TypeInt::INT; }
+ virtual uint ideal_reg() const { return Op_RegI; }
+};
+
+//---------- PopCountLNode -----------------------------------------------------
+// Population count (bit count) of a long.
+class PopCountLNode : public Node {
+public:
+ PopCountLNode(Node* in1) : Node(0, in1) {}
+ virtual int Opcode() const;
+ const Type* bottom_type() const { return TypeInt::INT; }
+ virtual uint ideal_reg() const { return Op_RegI; }
+};
diff --git a/src/share/vm/opto/library_call.cpp b/src/share/vm/opto/library_call.cpp
index 6cbcee84b..b5b7136a3 100644
--- a/src/share/vm/opto/library_call.cpp
+++ b/src/share/vm/opto/library_call.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1999-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -221,6 +221,7 @@ class LibraryCallKit : public GraphKit {
bool inline_unsafe_CAS(BasicType type);
bool inline_unsafe_ordered_store(BasicType type);
bool inline_fp_conversions(vmIntrinsics::ID id);
+ bool inline_bitCount(vmIntrinsics::ID id);
bool inline_reverseBytes(vmIntrinsics::ID id);
};
@@ -314,6 +315,11 @@ CallGenerator* Compile::make_vm_intrinsic(ciMethod* m, bool is_virtual) {
if (!JDK_Version::is_gte_jdk14x_version()) return NULL;
break;
+ case vmIntrinsics::_bitCount_i:
+ case vmIntrinsics::_bitCount_l:
+ if (!UsePopCountInstruction) return NULL;
+ break;
+
default:
break;
}
@@ -617,6 +623,10 @@ bool LibraryCallKit::try_to_inline() {
case vmIntrinsics::_longBitsToDouble:
return inline_fp_conversions(intrinsic_id());
+ case vmIntrinsics::_bitCount_i:
+ case vmIntrinsics::_bitCount_l:
+ return inline_bitCount(intrinsic_id());
+
case vmIntrinsics::_reverseBytes_i:
case vmIntrinsics::_reverseBytes_l:
return inline_reverseBytes((vmIntrinsics::ID) intrinsic_id());
@@ -1714,6 +1724,27 @@ inline Node* LibraryCallKit::make_unsafe_address(Node* base, Node* offset) {
}
}
+//----------------------------inline_bitCount_int/long-----------------------
+// inline int Integer.bitCount(int)
+// inline int Long.bitCount(long)
+bool LibraryCallKit::inline_bitCount(vmIntrinsics::ID id) {
+ assert(id == vmIntrinsics::_bitCount_i || id == vmIntrinsics::_bitCount_l, "not bitCount");
+ if (id == vmIntrinsics::_bitCount_i && !Matcher::has_match_rule(Op_PopCountI)) return false;
+ if (id == vmIntrinsics::_bitCount_l && !Matcher::has_match_rule(Op_PopCountL)) return false;
+ _sp += arg_size(); // restore stack pointer
+ switch (id) {
+ case vmIntrinsics::_bitCount_i:
+ push(_gvn.transform(new (C, 2) PopCountINode(pop())));
+ break;
+ case vmIntrinsics::_bitCount_l:
+ push(_gvn.transform(new (C, 2) PopCountLNode(pop_pair())));
+ break;
+ default:
+ ShouldNotReachHere();
+ }
+ return true;
+}
+
//----------------------------inline_reverseBytes_int/long-------------------
// inline Integer.reverseBytes(int)
// inline Long.reverseBytes(long)