mirror of
https://github.com/openjdk/jdk.git
synced 2026-05-26 13:27:59 +00:00
8166561: [s390] Adaptions needed for s390 port in C1 and C2
Reviewed-by: kvn
This commit is contained in:
parent
7aed968c10
commit
da8430daf1
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -72,6 +72,7 @@ define_pd_global(bool, OptoScheduling, false);
|
||||
define_pd_global(bool, OptoBundling, false);
|
||||
define_pd_global(bool, OptoRegScheduling, false);
|
||||
define_pd_global(bool, SuperWordLoopUnrollAnalysis, true);
|
||||
define_pd_global(bool, IdealizeClearArrayNode, true);
|
||||
|
||||
define_pd_global(intx, ReservedCodeCacheSize, 48*M);
|
||||
define_pd_global(intx, NonProfiledCodeHeapSize, 21*M);
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2015 SAP SE. All rights reserved.
|
||||
* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2016 SAP SE. 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
|
||||
@ -80,6 +80,7 @@ define_pd_global(bool, SuperWordLoopUnrollAnalysis, false);
|
||||
// loc = x.f
|
||||
// NullCheck loc
|
||||
define_pd_global(bool, OptoScheduling, false);
|
||||
define_pd_global(bool, IdealizeClearArrayNode, true);
|
||||
|
||||
define_pd_global(intx, InitialCodeCacheSize, 2048*K); // Integral multiple of CodeCacheExpansionSize
|
||||
define_pd_global(intx, ReservedCodeCacheSize, 256*M);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2016, Oracle and/or its affiliates. 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
|
||||
@ -64,6 +64,7 @@ define_pd_global(bool, OptoBundling, false);
|
||||
define_pd_global(bool, OptoScheduling, true);
|
||||
define_pd_global(bool, OptoRegScheduling, false);
|
||||
define_pd_global(bool, SuperWordLoopUnrollAnalysis, false);
|
||||
define_pd_global(bool, IdealizeClearArrayNode, true);
|
||||
|
||||
#ifdef _LP64
|
||||
// We need to make sure that all generated code is within
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2016, Oracle and/or its affiliates. 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
|
||||
@ -83,6 +83,7 @@ define_pd_global(bool, OptoScheduling, false);
|
||||
define_pd_global(bool, OptoBundling, false);
|
||||
define_pd_global(bool, OptoRegScheduling, true);
|
||||
define_pd_global(bool, SuperWordLoopUnrollAnalysis, true);
|
||||
define_pd_global(bool, IdealizeClearArrayNode, true);
|
||||
|
||||
define_pd_global(intx, ReservedCodeCacheSize, 48*M);
|
||||
define_pd_global(intx, NonProfiledCodeHeapSize, 21*M);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2016, Oracle and/or its affiliates. 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
|
||||
@ -722,6 +722,11 @@ int InstructForm::memory_operand(FormDict &globals) const {
|
||||
// // unique def, some uses
|
||||
// // must return bottom unless all uses match def
|
||||
// unique = NULL;
|
||||
#ifdef S390
|
||||
// This case is important for move instructions on s390x.
|
||||
// On other platforms (e.g. x86), all uses always match the def.
|
||||
unique = NULL;
|
||||
#endif
|
||||
}
|
||||
} else if( DEF_of_memory > 0 ) {
|
||||
// multiple defs, don't care about uses
|
||||
|
||||
@ -259,6 +259,7 @@ int main(int argc, char *argv[])
|
||||
AD.addInclude(AD._DFA_file, "opto/cfgnode.hpp"); // Use PROB_MAX in predicate.
|
||||
AD.addInclude(AD._DFA_file, "opto/intrinsicnode.hpp");
|
||||
AD.addInclude(AD._DFA_file, "opto/matcher.hpp");
|
||||
AD.addInclude(AD._DFA_file, "opto/narrowptrnode.hpp");
|
||||
AD.addInclude(AD._DFA_file, "opto/opcodes.hpp");
|
||||
AD.addInclude(AD._DFA_file, "opto/convertnode.hpp");
|
||||
// Make sure each .cpp file starts with include lines:
|
||||
|
||||
@ -209,6 +209,17 @@ void LIR_Op2::verify() const {
|
||||
}
|
||||
|
||||
if (TwoOperandLIRForm) {
|
||||
|
||||
#ifdef ASSERT
|
||||
bool threeOperandForm = false;
|
||||
#ifdef S390
|
||||
// There are 3 operand shifts on S390 (see LIR_Assembler::shift_op()).
|
||||
threeOperandForm =
|
||||
code() == lir_shl ||
|
||||
((code() == lir_shr || code() == lir_ushr) && (result_opr()->is_double_cpu() || in_opr1()->type() == T_OBJECT));
|
||||
#endif
|
||||
#endif
|
||||
|
||||
switch (code()) {
|
||||
case lir_add:
|
||||
case lir_sub:
|
||||
@ -222,13 +233,13 @@ void LIR_Op2::verify() const {
|
||||
case lir_logic_xor:
|
||||
case lir_shl:
|
||||
case lir_shr:
|
||||
assert(in_opr1() == result_opr(), "opr1 and result must match");
|
||||
assert(in_opr1() == result_opr() || threeOperandForm, "opr1 and result must match");
|
||||
assert(in_opr1()->is_valid() && in_opr2()->is_valid(), "must be valid");
|
||||
break;
|
||||
|
||||
// special handling for lir_ushr because of write barriers
|
||||
case lir_ushr:
|
||||
assert(in_opr1() == result_opr() || in_opr2()->is_constant(), "opr1 and result must match or shift count is constant");
|
||||
assert(in_opr1() == result_opr() || in_opr2()->is_constant() || threeOperandForm, "opr1 and result must match or shift count is constant");
|
||||
assert(in_opr1()->is_valid() && in_opr2()->is_valid(), "must be valid");
|
||||
break;
|
||||
|
||||
|
||||
@ -606,7 +606,10 @@ void LIRGenerator::arithmetic_op_fpu(Bytecodes::Code code, LIR_Opr result, LIR_O
|
||||
|
||||
|
||||
void LIRGenerator::shift_op(Bytecodes::Code code, LIR_Opr result_op, LIR_Opr value, LIR_Opr count, LIR_Opr tmp) {
|
||||
if (TwoOperandLIRForm && value != result_op) {
|
||||
|
||||
if (TwoOperandLIRForm && value != result_op
|
||||
// Only 32bit right shifts require two operand form on S390.
|
||||
S390_ONLY(&& (code == Bytecodes::_ishr || code == Bytecodes::_iushr))) {
|
||||
assert(count != result_op, "malformed");
|
||||
__ move(value, result_op);
|
||||
value = result_op;
|
||||
|
||||
@ -28,6 +28,7 @@
|
||||
#include "c1/c1_Instruction.hpp"
|
||||
#include "c1/c1_LIR.hpp"
|
||||
#include "ci/ciMethodData.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
#include "utilities/sizes.hpp"
|
||||
|
||||
// The classes responsible for code emission and register allocation
|
||||
@ -360,7 +361,7 @@ class LIRGenerator: public InstructionVisitor, public BlockClosure {
|
||||
void add_large_constant(LIR_Opr src, int c, LIR_Opr dest);
|
||||
|
||||
// machine preferences and characteristics
|
||||
bool can_inline_as_constant(Value i) const;
|
||||
bool can_inline_as_constant(Value i S390_ONLY(COMMA int bits = 20)) const;
|
||||
bool can_inline_as_constant(LIR_Const* c) const;
|
||||
bool can_store_as_constant(Value i, BasicType type) const;
|
||||
|
||||
@ -497,6 +498,12 @@ class LIRGenerator: public InstructionVisitor, public BlockClosure {
|
||||
static LIR_Opr divInOpr();
|
||||
static LIR_Opr divOutOpr();
|
||||
static LIR_Opr remOutOpr();
|
||||
#ifdef S390
|
||||
// On S390 we can do ldiv, lrem without RT call.
|
||||
static LIR_Opr ldivInOpr();
|
||||
static LIR_Opr ldivOutOpr();
|
||||
static LIR_Opr lremOutOpr();
|
||||
#endif
|
||||
static LIR_Opr shiftCountOpr();
|
||||
LIR_Opr syncLockOpr();
|
||||
LIR_Opr syncTempOpr();
|
||||
@ -622,7 +629,7 @@ class LIRItem: public CompilationResourceObj {
|
||||
|
||||
void load_item();
|
||||
void load_byte_item();
|
||||
void load_nonconstant();
|
||||
void load_nonconstant(S390_ONLY(int bits = 20));
|
||||
// load any values which can't be expressed as part of a single store instruction
|
||||
void load_for_store(BasicType store_type);
|
||||
void load_item_force(LIR_Opr reg);
|
||||
|
||||
@ -1077,7 +1077,7 @@ IntervalUseKind LinearScan::use_kind_of_input_operand(LIR_Op* op, LIR_Opr opr) {
|
||||
}
|
||||
|
||||
|
||||
#ifdef X86
|
||||
#if defined(X86) || defined(S390)
|
||||
if (op->code() == lir_cmove) {
|
||||
// conditional moves can handle stack operands
|
||||
assert(op->result_opr()->is_register(), "result must always be in a register");
|
||||
@ -1088,7 +1088,7 @@ IntervalUseKind LinearScan::use_kind_of_input_operand(LIR_Op* op, LIR_Opr opr) {
|
||||
// this operand is allowed to be on the stack in some cases
|
||||
BasicType opr_type = opr->type_register();
|
||||
if (opr_type == T_FLOAT || opr_type == T_DOUBLE) {
|
||||
if ((UseSSE == 1 && opr_type == T_FLOAT) || UseSSE >= 2) {
|
||||
if ((UseSSE == 1 && opr_type == T_FLOAT) || UseSSE >= 2 S390_ONLY(|| true)) {
|
||||
// SSE float instruction (T_DOUBLE only supported with SSE2)
|
||||
switch (op->code()) {
|
||||
case lir_cmp:
|
||||
@ -1144,7 +1144,7 @@ IntervalUseKind LinearScan::use_kind_of_input_operand(LIR_Op* op, LIR_Opr opr) {
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // X86
|
||||
#endif // X86 S390
|
||||
|
||||
// all other operands require a register
|
||||
return mustHaveRegister;
|
||||
@ -2653,6 +2653,11 @@ int LinearScan::append_scope_value_for_operand(LIR_Opr opr, GrowableArray<ScopeV
|
||||
VMReg rname = frame_map()->fpu_regname(opr->fpu_regnr());
|
||||
#ifndef __SOFTFP__
|
||||
#ifndef VM_LITTLE_ENDIAN
|
||||
// On S390 a (single precision) float value occupies only the high
|
||||
// word of the full double register. So when the double register is
|
||||
// stored to memory (e.g. by the RegisterSaver), then the float value
|
||||
// is found at offset 0. I.e. the code below is not needed on S390.
|
||||
#ifndef S390
|
||||
if (! float_saved_as_double) {
|
||||
// On big endian system, we may have an issue if float registers use only
|
||||
// the low half of the (same) double registers.
|
||||
@ -2667,6 +2672,7 @@ int LinearScan::append_scope_value_for_operand(LIR_Opr opr, GrowableArray<ScopeV
|
||||
rname = next; // VMReg for the low bits, e.g. the real VMReg for the float
|
||||
}
|
||||
}
|
||||
#endif // !S390
|
||||
#endif
|
||||
#endif
|
||||
LocationValue* sv = new LocationValue(Location::new_reg_loc(loc_type, rname));
|
||||
|
||||
@ -120,6 +120,9 @@
|
||||
"Check performance difference allowing FP " \
|
||||
"associativity and commutativity...") \
|
||||
\
|
||||
diagnostic_pd(bool, IdealizeClearArrayNode, \
|
||||
"Replace ClearArrayNode by subgraph of basic operations.") \
|
||||
\
|
||||
develop(bool, OptoBreakpoint, false, \
|
||||
"insert breakpoint at method entry") \
|
||||
\
|
||||
|
||||
@ -2717,9 +2717,9 @@ Node* ClearArrayNode::Identity(PhaseGVN* phase) {
|
||||
|
||||
//------------------------------Idealize---------------------------------------
|
||||
// Clearing a short array is faster with stores
|
||||
Node *ClearArrayNode::Ideal(PhaseGVN *phase, bool can_reshape){
|
||||
Node *ClearArrayNode::Ideal(PhaseGVN *phase, bool can_reshape) {
|
||||
// Already know this is a large node, do not try to ideal it
|
||||
if (_is_large) return NULL;
|
||||
if (!IdealizeClearArrayNode || _is_large) return NULL;
|
||||
|
||||
const int unit = BytesPerLong;
|
||||
const TypeX* t = phase->type(in(2))->isa_intptr_t();
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2016, Oracle and/or its affiliates. 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
|
||||
@ -1206,13 +1206,19 @@ void Compile::fill_buffer(CodeBuffer* cb, uint* blk_starts) {
|
||||
padding = nop_size;
|
||||
}
|
||||
|
||||
if(padding > 0) {
|
||||
if (padding > 0) {
|
||||
assert((padding % nop_size) == 0, "padding is not a multiple of NOP size");
|
||||
int nops_cnt = padding / nop_size;
|
||||
MachNode *nop = new MachNopNode(nops_cnt);
|
||||
block->insert_node(nop, j++);
|
||||
last_inst++;
|
||||
_cfg->map_node_to_block(nop, block);
|
||||
// Ensure enough space.
|
||||
cb->insts()->maybe_expand_to_ensure_remaining(MAX_inst_size);
|
||||
if ((cb->blob() == NULL) || (!CompileBroker::should_compile_new_jobs())) {
|
||||
C->record_failure("CodeCache is full");
|
||||
return;
|
||||
}
|
||||
nop->emit(*cb, _regalloc);
|
||||
cb->flush_bundle(true);
|
||||
current_offset = cb->insts_size();
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. 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
|
||||
@ -67,7 +67,7 @@ Type::TypeInfo Type::_type_info[Type::lastype] = {
|
||||
{ Bad, T_ILLEGAL, "vectorx:", false, 0, relocInfo::none }, // VectorX
|
||||
{ Bad, T_ILLEGAL, "vectory:", false, 0, relocInfo::none }, // VectorY
|
||||
{ Bad, T_ILLEGAL, "vectorz:", false, 0, relocInfo::none }, // VectorZ
|
||||
#elif defined(PPC64)
|
||||
#elif defined(PPC64) || defined(S390)
|
||||
{ Bad, T_ILLEGAL, "vectors:", false, 0, relocInfo::none }, // VectorS
|
||||
{ Bad, T_ILLEGAL, "vectord:", false, Op_RegL, relocInfo::none }, // VectorD
|
||||
{ Bad, T_ILLEGAL, "vectorx:", false, 0, relocInfo::none }, // VectorX
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. 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
|
||||
@ -361,6 +361,8 @@ Flag::Error InteriorEntryAlignmentConstraintFunc(intx value, bool verbose) {
|
||||
int minimum_alignment = 16;
|
||||
#if defined(SPARC) || (defined(X86) && !defined(AMD64))
|
||||
minimum_alignment = 4;
|
||||
#elif defined(S390)
|
||||
minimum_alignment = 2;
|
||||
#endif
|
||||
|
||||
if (InteriorEntryAlignment < minimum_alignment) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user