From 1b3888bbea1fa1544d79d5c16f21c7e62cc62e8e Mon Sep 17 00:00:00 2001 From: roland Date: Fri, 25 Mar 2011 09:35:39 +0100 Subject: [PATCH] 7029017: Additional architecture support for c2 compiler Summary: Enables cross building of a c2 VM. Support masking of shift counts when the processor architecture mandates it. Reviewed-by: kvn, never --- make/linux/makefiles/adlc.make | 6 +++--- make/linux/makefiles/gcc.make | 4 ++++ make/linux/makefiles/rules.make | 8 ++++++++ make/linux/makefiles/sparcWorks.make | 3 +++ src/cpu/sparc/vm/sparc.ad | 4 ++++ src/cpu/x86/vm/x86_32.ad | 4 ++++ src/cpu/x86/vm/x86_64.ad | 4 ++++ src/share/vm/adlc/main.cpp | 5 +++++ src/share/vm/opto/chaitin.cpp | 2 +- src/share/vm/opto/compile.cpp | 30 ++++++++++++++++++++++++++++ src/share/vm/opto/lcm.cpp | 3 +++ src/share/vm/opto/matcher.cpp | 3 +++ src/share/vm/opto/matcher.hpp | 5 +++++ 13 files changed, 77 insertions(+), 4 deletions(-) diff --git a/make/linux/makefiles/adlc.make b/make/linux/makefiles/adlc.make index 84ff8f88c..0c15c1c65 100644 --- a/make/linux/makefiles/adlc.make +++ b/make/linux/makefiles/adlc.make @@ -102,7 +102,7 @@ all: $(EXEC) $(EXEC) : $(OBJECTS) @echo Making adlc - $(QUIETLY) $(LINK_NOPROF.CC) -o $(EXEC) $(OBJECTS) + $(QUIETLY) $(HOST.LINK_NOPROF.CC) -o $(EXEC) $(OBJECTS) # Random dependencies: $(OBJECTS): opcodes.hpp classes.hpp adlc.hpp adlcVMDeps.hpp adlparse.hpp archDesc.hpp arena.hpp dict2.hpp filebuff.hpp forms.hpp formsopt.hpp formssel.hpp @@ -204,14 +204,14 @@ PROCESS_AD_FILES = awk '{ \ $(OUTDIR)/%.o: %.cpp @echo Compiling $< $(QUIETLY) $(REMOVE_TARGET) - $(QUIETLY) $(COMPILE.CC) -o $@ $< $(COMPILE_DONE) + $(QUIETLY) $(HOST.COMPILE.CC) -o $@ $< $(COMPILE_DONE) # Some object files are given a prefix, to disambiguate # them from objects of the same name built for the VM. $(OUTDIR)/adlc-%.o: %.cpp @echo Compiling $< $(QUIETLY) $(REMOVE_TARGET) - $(QUIETLY) $(COMPILE.CC) -o $@ $< $(COMPILE_DONE) + $(QUIETLY) $(HOST.COMPILE.CC) -o $@ $< $(COMPILE_DONE) # ######################################################################### diff --git a/make/linux/makefiles/gcc.make b/make/linux/makefiles/gcc.make index 04c407bce..28105c41a 100644 --- a/make/linux/makefiles/gcc.make +++ b/make/linux/makefiles/gcc.make @@ -30,9 +30,13 @@ ifdef CROSS_COMPILE_ARCH CPP = $(ALT_COMPILER_PATH)/g++ CC = $(ALT_COMPILER_PATH)/gcc +HOSTCPP = g++ +HOSTCC = gcc else CPP = g++ CC = gcc +HOSTCPP = $(CPP) +HOSTCC = $(CC) endif AS = $(CC) -c diff --git a/make/linux/makefiles/rules.make b/make/linux/makefiles/rules.make index 4237597e9..12eafe8b3 100644 --- a/make/linux/makefiles/rules.make +++ b/make/linux/makefiles/rules.make @@ -55,6 +55,14 @@ LINK_NOPROF.CC = $(CCC) $(LFLAGS) $(AOUT_FLAGS) LINK_LIB.CC = $(CCC) $(LFLAGS) $(SHARED_FLAG) PREPROCESS.CC = $(CC_COMPILE) -E +# cross compiling the jvm with c2 requires host compilers to build +# adlc tool + +HOST.CC_COMPILE = $(HOSTCPP) $(CPPFLAGS) $(CFLAGS) +HOST.COMPILE.CC = $(HOST.CC_COMPILE) -c +HOST.LINK_NOPROF.CC = $(HOSTCPP) $(LFLAGS) $(AOUT_FLAGS) + + # Effect of REMOVE_TARGET is to delete out-of-date files during "gnumake -k". REMOVE_TARGET = rm -f $@ diff --git a/make/linux/makefiles/sparcWorks.make b/make/linux/makefiles/sparcWorks.make index 77076fff1..818ef42b0 100644 --- a/make/linux/makefiles/sparcWorks.make +++ b/make/linux/makefiles/sparcWorks.make @@ -29,6 +29,9 @@ CPP = CC CC = cc AS = $(CC) -c +HOSTCPP = $(CPP) +HOSTCC = $(CC) + ARCHFLAG = $(ARCHFLAG/$(BUILDARCH)) ARCHFLAG/i486 = -m32 ARCHFLAG/amd64 = -m64 diff --git a/src/cpu/sparc/vm/sparc.ad b/src/cpu/sparc/vm/sparc.ad index cffc8fb5f..f2d7656d3 100644 --- a/src/cpu/sparc/vm/sparc.ad +++ b/src/cpu/sparc/vm/sparc.ad @@ -1843,6 +1843,10 @@ const int Matcher::init_array_short_size = 8 * BytesPerLong; // registers? True for Intel but false for most RISCs const bool Matcher::clone_shift_expressions = false; +// Do we need to mask the count passed to shift instructions or does +// the cpu only look at the lower 5/6 bits anyway? +const bool Matcher::need_masked_shift_count = false; + bool Matcher::narrow_oop_use_complex_address() { NOT_LP64(ShouldNotCallThis()); assert(UseCompressedOops, "only for compressed oops code"); diff --git a/src/cpu/x86/vm/x86_32.ad b/src/cpu/x86/vm/x86_32.ad index 6fdb24f93..e9cf81147 100644 --- a/src/cpu/x86/vm/x86_32.ad +++ b/src/cpu/x86/vm/x86_32.ad @@ -1393,6 +1393,10 @@ const int Matcher::init_array_short_size = 8 * BytesPerLong; // registers? True for Intel but false for most RISCs const bool Matcher::clone_shift_expressions = true; +// Do we need to mask the count passed to shift instructions or does +// the cpu only look at the lower 5/6 bits anyway? +const bool Matcher::need_masked_shift_count = false; + bool Matcher::narrow_oop_use_complex_address() { ShouldNotCallThis(); return true; diff --git a/src/cpu/x86/vm/x86_64.ad b/src/cpu/x86/vm/x86_64.ad index 2466269c6..b0835d208 100644 --- a/src/cpu/x86/vm/x86_64.ad +++ b/src/cpu/x86/vm/x86_64.ad @@ -2000,6 +2000,10 @@ const int Matcher::init_array_short_size = 8 * BytesPerLong; // into registers? True for Intel but false for most RISCs const bool Matcher::clone_shift_expressions = true; +// Do we need to mask the count passed to shift instructions or does +// the cpu only look at the lower 5/6 bits anyway? +const bool Matcher::need_masked_shift_count = false; + bool Matcher::narrow_oop_use_complex_address() { assert(UseCompressedOops, "only for compressed oops code"); return (LogMinObjAlignmentInBytes <= 3); diff --git a/src/share/vm/adlc/main.cpp b/src/share/vm/adlc/main.cpp index 3d74a4f02..88a75e684 100644 --- a/src/share/vm/adlc/main.cpp +++ b/src/share/vm/adlc/main.cpp @@ -239,6 +239,11 @@ int main(int argc, char *argv[]) AD.addInclude(AD._CPP_file, "assembler_sparc.inline.hpp"); AD.addInclude(AD._CPP_file, "nativeInst_sparc.hpp"); AD.addInclude(AD._CPP_file, "vmreg_sparc.inline.hpp"); +#endif +#ifdef TARGET_ARCH_arm + AD.addInclude(AD._CPP_file, "assembler_arm.inline.hpp"); + AD.addInclude(AD._CPP_file, "nativeInst_arm.hpp"); + AD.addInclude(AD._CPP_file, "vmreg_arm.inline.hpp"); #endif AD.addInclude(AD._HPP_file, "memory/allocation.hpp"); AD.addInclude(AD._HPP_file, "opto/machnode.hpp"); diff --git a/src/share/vm/opto/chaitin.cpp b/src/share/vm/opto/chaitin.cpp index 6108084f9..3c363e9ff 100644 --- a/src/share/vm/opto/chaitin.cpp +++ b/src/share/vm/opto/chaitin.cpp @@ -673,7 +673,7 @@ void PhaseChaitin::gather_lrg_masks( bool after_aggressive ) { case Op_RegD: lrg.set_num_regs(2); // Define platform specific register pressure -#ifdef SPARC +#if defined(SPARC) || defined(ARM) lrg.set_reg_pressure(2); #elif defined(IA32) if( ireg == Op_RegL ) { diff --git a/src/share/vm/opto/compile.cpp b/src/share/vm/opto/compile.cpp index c9e04bb7a..39bcf30bd 100644 --- a/src/share/vm/opto/compile.cpp +++ b/src/share/vm/opto/compile.cpp @@ -2544,6 +2544,36 @@ static void final_graph_reshaping_impl( Node *n, Final_Reshape_Counts &frc ) { frc.inc_inner_loop_count(); } break; + case Op_LShiftI: + case Op_RShiftI: + case Op_URShiftI: + case Op_LShiftL: + case Op_RShiftL: + case Op_URShiftL: + if (Matcher::need_masked_shift_count) { + // The cpu's shift instructions don't restrict the count to the + // lower 5/6 bits. We need to do the masking ourselves. + Node* in2 = n->in(2); + juint mask = (n->bottom_type() == TypeInt::INT) ? (BitsPerInt - 1) : (BitsPerLong - 1); + const TypeInt* t = in2->find_int_type(); + if (t != NULL && t->is_con()) { + juint shift = t->get_con(); + if (shift > mask) { // Unsigned cmp + Compile* C = Compile::current(); + n->set_req(2, ConNode::make(C, TypeInt::make(shift & mask))); + } + } else { + if (t == NULL || t->_lo < 0 || t->_hi > (int)mask) { + Compile* C = Compile::current(); + Node* shift = new (C, 3) AndINode(in2, ConNode::make(C, TypeInt::make(mask))); + n->set_req(2, shift); + } + } + if (in2->outcnt() == 0) { // Remove dead node + in2->disconnect_inputs(NULL); + } + } + break; default: assert( !n->is_Call(), "" ); assert( !n->is_Mem(), "" ); diff --git a/src/share/vm/opto/lcm.cpp b/src/share/vm/opto/lcm.cpp index 3d84f6baf..fd3343c3c 100644 --- a/src/share/vm/opto/lcm.cpp +++ b/src/share/vm/opto/lcm.cpp @@ -42,6 +42,9 @@ #ifdef TARGET_ARCH_MODEL_zero # include "adfiles/ad_zero.hpp" #endif +#ifdef TARGET_ARCH_MODEL_arm +# include "adfiles/ad_arm.hpp" +#endif // Optimization - Graph Style diff --git a/src/share/vm/opto/matcher.cpp b/src/share/vm/opto/matcher.cpp index 2bd3acd6f..48ff22d10 100644 --- a/src/share/vm/opto/matcher.cpp +++ b/src/share/vm/opto/matcher.cpp @@ -49,6 +49,9 @@ #ifdef TARGET_ARCH_MODEL_zero # include "adfiles/ad_zero.hpp" #endif +#ifdef TARGET_ARCH_MODEL_arm +# include "adfiles/ad_arm.hpp" +#endif OptoReg::Name OptoReg::c_frame_pointer; diff --git a/src/share/vm/opto/matcher.hpp b/src/share/vm/opto/matcher.hpp index c1627c60f..e8d3c99f8 100644 --- a/src/share/vm/opto/matcher.hpp +++ b/src/share/vm/opto/matcher.hpp @@ -427,6 +427,11 @@ public: // Do ints take an entire long register or just half? static const bool int_in_long; + // Do the processor's shift instructions only use the low 5/6 bits + // of the count for 32/64 bit ints? If not we need to do the masking + // ourselves. + static const bool need_masked_shift_count; + // This routine is run whenever a graph fails to match. // If it returns, the compiler should bailout to interpreter without error. // In non-product mode, SoftMatchFailure is false to detect non-canonical -- GitLab