src/share/vm/opto/matcher.cpp
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File
*** old/src/share/vm/opto/matcher.cpp Sat Jun 2 20:04:14 2012
--- new/src/share/vm/opto/matcher.cpp Sat Jun 2 20:04:14 2012
*** 1,7 ****
--- 1,7 ----
/*
! * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
! * Copyright (c) 1997, 2012, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*** 33,42 ****
--- 33,43 ----
#include "opto/opcodes.hpp"
#include "opto/regmask.hpp"
#include "opto/rootnode.hpp"
#include "opto/runtime.hpp"
#include "opto/type.hpp"
+ #include "opto/vectornode.hpp"
#include "runtime/atomic.hpp"
#include "runtime/os.hpp"
#ifdef TARGET_ARCH_MODEL_x86_32
# include "adfiles/ad_x86_32.hpp"
#endif
*** 56,77 ****
--- 57,66 ----
# include "adfiles/ad_ppc.hpp"
#endif
OptoReg::Name OptoReg::c_frame_pointer;
const int Matcher::base2reg[Type::lastype] = {
Node::NotAMachineReg,0,0, Op_RegI, Op_RegL, 0, Op_RegN,
Node::NotAMachineReg, Node::NotAMachineReg, /* tuple, array */
Op_RegP, Op_RegP, Op_RegP, Op_RegP, Op_RegP, Op_RegP, /* the pointers */
0, 0/*abio*/,
Op_RegP /* Return address */, 0, /* the memories */
Op_RegF, Op_RegF, Op_RegF, Op_RegD, Op_RegD, Op_RegD,
0 /*bottom*/
};
const RegMask *Matcher::idealreg2regmask[_last_machine_leaf];
RegMask Matcher::mreg2regmask[_last_Mach_Reg];
RegMask Matcher::STACK_ONLY_mask;
RegMask Matcher::c_frame_ptr_mask;
const uint Matcher::_begin_rematerialize = _BEGIN_REMATERIALIZE;
*** 105,128 ****
--- 94,129 ----
idealreg2spillmask [Op_RegN] = NULL;
idealreg2spillmask [Op_RegL] = NULL;
idealreg2spillmask [Op_RegF] = NULL;
idealreg2spillmask [Op_RegD] = NULL;
idealreg2spillmask [Op_RegP] = NULL;
+ idealreg2spillmask [Op_VecS] = NULL;
+ idealreg2spillmask [Op_VecD] = NULL;
+ idealreg2spillmask [Op_VecX] = NULL;
+ idealreg2spillmask [Op_VecY] = NULL;
idealreg2debugmask [Op_RegI] = NULL;
idealreg2debugmask [Op_RegN] = NULL;
idealreg2debugmask [Op_RegL] = NULL;
idealreg2debugmask [Op_RegF] = NULL;
idealreg2debugmask [Op_RegD] = NULL;
idealreg2debugmask [Op_RegP] = NULL;
+ idealreg2debugmask [Op_VecS] = NULL;
+ idealreg2debugmask [Op_VecD] = NULL;
+ idealreg2debugmask [Op_VecX] = NULL;
+ idealreg2debugmask [Op_VecY] = NULL;
idealreg2mhdebugmask[Op_RegI] = NULL;
idealreg2mhdebugmask[Op_RegN] = NULL;
idealreg2mhdebugmask[Op_RegL] = NULL;
idealreg2mhdebugmask[Op_RegF] = NULL;
idealreg2mhdebugmask[Op_RegD] = NULL;
idealreg2mhdebugmask[Op_RegP] = NULL;
+ idealreg2mhdebugmask[Op_VecS] = NULL;
+ idealreg2mhdebugmask[Op_VecD] = NULL;
+ idealreg2mhdebugmask[Op_VecX] = NULL;
+ idealreg2mhdebugmask[Op_VecY] = NULL;
debug_only(_mem_node = NULL;) // Ideal memory node consumed by mach node
}
//------------------------------warp_incoming_stk_arg------------------------
*** 132,142 ****
--- 133,143 ----
if( reg->is_stack() ) { // Stack slot argument?
warped = OptoReg::add(_old_SP, reg->reg2stack() );
warped = OptoReg::add(warped, C->out_preserve_stack_slots());
if( warped >= _in_arg_limit )
_in_arg_limit = OptoReg::add(warped, 1); // Bump max stack slot seen
! if (!RegMask::can_represent_arg(warped)) {
// the compiler cannot represent this method's calling sequence
C->record_method_not_compilable_all_tiers("unsupported incoming calling sequence");
return OptoReg::Bad;
}
return warped;
*** 300,310 ****
--- 301,311 ----
// Compute highest outgoing stack argument as
// _new_SP + out_preserve_stack_slots + max(outgoing argument size).
_out_arg_limit = OptoReg::add(_new_SP, C->out_preserve_stack_slots());
assert( is_even(_out_arg_limit), "out_preserve must be even" );
! if (!RegMask::can_represent_arg(OptoReg::add(_out_arg_limit,-1))) {
// the compiler cannot represent this method's calling sequence
C->record_method_not_compilable("must be able to represent all call arguments in reg mask");
}
if (C->failing()) return; // bailed out on incoming arg failure
*** 426,436 ****
--- 427,437 ----
// Disallow any debug info in outgoing argument areas by setting the
// initial mask accordingly.
void Matcher::init_first_stack_mask() {
// Allocate storage for spill masks as masks for the appropriate load type.
! RegMask *rms = (RegMask*)C->comp_arena()->Amalloc_D(sizeof(RegMask) * (3*6+4));
idealreg2spillmask [Op_RegN] = &rms[0];
idealreg2spillmask [Op_RegI] = &rms[1];
idealreg2spillmask [Op_RegL] = &rms[2];
idealreg2spillmask [Op_RegF] = &rms[3];
*** 449,458 ****
--- 450,464 ----
idealreg2mhdebugmask[Op_RegL] = &rms[14];
idealreg2mhdebugmask[Op_RegF] = &rms[15];
idealreg2mhdebugmask[Op_RegD] = &rms[16];
idealreg2mhdebugmask[Op_RegP] = &rms[17];
+ idealreg2spillmask [Op_VecS] = &rms[18];
+ idealreg2spillmask [Op_VecD] = &rms[19];
+ idealreg2spillmask [Op_VecX] = &rms[20];
+ idealreg2spillmask [Op_VecY] = &rms[21];
+
OptoReg::Name i;
// At first, start with the empty mask
C->FIRST_STACK_mask().Clear();
*** 460,494 ****
--- 466,527 ----
OptoReg::Name init = OptoReg::add(_old_SP, C->out_preserve_stack_slots());
for (i = init; i < _in_arg_limit; i = OptoReg::add(i,1))
C->FIRST_STACK_mask().Insert(i);
// Add in all bits past the outgoing argument area
! guarantee(RegMask::can_represent_arg(OptoReg::add(_out_arg_limit,-1)),
"must be able to represent all call arguments in reg mask");
init = _out_arg_limit;
for (i = init; RegMask::can_represent(i); i = OptoReg::add(i,1))
C->FIRST_STACK_mask().Insert(i);
// Finally, set the "infinite stack" bit.
C->FIRST_STACK_mask().set_AllStack();
// Make spill masks. Registers for their class, plus FIRST_STACK_mask.
+ RegMask aligned_stack_mask = C->FIRST_STACK_mask();
+ // Keep spill masks aligned.
+ aligned_stack_mask.clear_to_pairs();
+ assert(aligned_stack_mask.is_AllStack(), "should be infinite stack");
+
+ *idealreg2spillmask[Op_RegP] = *idealreg2regmask[Op_RegP];
#ifdef _LP64
*idealreg2spillmask[Op_RegN] = *idealreg2regmask[Op_RegN];
idealreg2spillmask[Op_RegN]->OR(C->FIRST_STACK_mask());
+ idealreg2spillmask[Op_RegP]->OR(aligned_stack_mask);
+ #else
+ idealreg2spillmask[Op_RegP]->OR(C->FIRST_STACK_mask());
#endif
*idealreg2spillmask[Op_RegI] = *idealreg2regmask[Op_RegI];
idealreg2spillmask[Op_RegI]->OR(C->FIRST_STACK_mask());
*idealreg2spillmask[Op_RegL] = *idealreg2regmask[Op_RegL];
! idealreg2spillmask[Op_RegL]->OR(C->FIRST_STACK_mask());
! idealreg2spillmask[Op_RegL]->OR(aligned_stack_mask);
*idealreg2spillmask[Op_RegF] = *idealreg2regmask[Op_RegF];
idealreg2spillmask[Op_RegF]->OR(C->FIRST_STACK_mask());
*idealreg2spillmask[Op_RegD] = *idealreg2regmask[Op_RegD];
! idealreg2spillmask[Op_RegD]->OR(C->FIRST_STACK_mask());
*idealreg2spillmask[Op_RegP] = *idealreg2regmask[Op_RegP];
idealreg2spillmask[Op_RegP]->OR(C->FIRST_STACK_mask());
! idealreg2spillmask[Op_RegD]->OR(aligned_stack_mask);
+ if (Matcher::vector_size_supported(T_BYTE,4)) {
+ *idealreg2spillmask[Op_VecS] = *idealreg2regmask[Op_VecS];
+ idealreg2spillmask[Op_VecS]->OR(C->FIRST_STACK_mask());
+ }
+ if (Matcher::vector_size_supported(T_FLOAT,2)) {
+ *idealreg2spillmask[Op_VecD] = *idealreg2regmask[Op_VecD];
+ idealreg2spillmask[Op_VecD]->OR(aligned_stack_mask);
+ }
+ if (Matcher::vector_size_supported(T_FLOAT,4)) {
+ aligned_stack_mask.clear_to_sets(RegMask::SlotsPerVecX);
+ assert(aligned_stack_mask.is_AllStack(), "should be infinite stack");
+ *idealreg2spillmask[Op_VecX] = *idealreg2regmask[Op_VecX];
+ idealreg2spillmask[Op_VecX]->OR(aligned_stack_mask);
+ }
+ if (Matcher::vector_size_supported(T_FLOAT,8)) {
+ aligned_stack_mask.clear_to_sets(RegMask::SlotsPerVecY);
+ assert(aligned_stack_mask.is_AllStack(), "should be infinite stack");
+ *idealreg2spillmask[Op_VecY] = *idealreg2regmask[Op_VecY];
+ idealreg2spillmask[Op_VecY]->OR(aligned_stack_mask);
+ }
if (UseFPUForSpilling) {
// This mask logic assumes that the spill operations are
// symmetric and that the registers involved are the same size.
// On sparc for instance we may have to use 64 bit moves will
// kill 2 registers when used with F0-F31.
*** 805,814 ****
--- 838,866 ----
idealreg2regmask[Op_RegI] = &spillI->out_RegMask();
idealreg2regmask[Op_RegL] = &spillL->out_RegMask();
idealreg2regmask[Op_RegF] = &spillF->out_RegMask();
idealreg2regmask[Op_RegD] = &spillD->out_RegMask();
idealreg2regmask[Op_RegP] = &spillP->out_RegMask();
+
+ // Vector regmasks.
+ if (Matcher::vector_size_supported(T_BYTE,4)) {
+ TypeVect::VECTS = TypeVect::make(T_BYTE, 4);
+ MachNode *spillVectS = match_tree(new (C, 3) LoadVectorNode(NULL,mem,fp,atp,TypeVect::VECTS));
+ idealreg2regmask[Op_VecS] = &spillVectS->out_RegMask();
+ }
+ if (Matcher::vector_size_supported(T_FLOAT,2)) {
+ MachNode *spillVectD = match_tree(new (C, 3) LoadVectorNode(NULL,mem,fp,atp,TypeVect::VECTD));
+ idealreg2regmask[Op_VecD] = &spillVectD->out_RegMask();
+ }
+ if (Matcher::vector_size_supported(T_FLOAT,4)) {
+ MachNode *spillVectX = match_tree(new (C, 3) LoadVectorNode(NULL,mem,fp,atp,TypeVect::VECTX));
+ idealreg2regmask[Op_VecX] = &spillVectX->out_RegMask();
+ }
+ if (Matcher::vector_size_supported(T_FLOAT,8)) {
+ MachNode *spillVectY = match_tree(new (C, 3) LoadVectorNode(NULL,mem,fp,atp,TypeVect::VECTY));
+ idealreg2regmask[Op_VecY] = &spillVectY->out_RegMask();
+ }
}
#ifdef ASSERT
static void match_alias_type(Compile* C, Node* n, Node* m) {
if (!VerifyAliases) return; // do not go looking for trouble by default
*** 1061,1071 ****
--- 1113,1123 ----
// Keep track of the largest numbered stack slot used for an arg.
// Largest used slot per call-site indicates the amount of stack
// that is killed by the call.
if( warped >= out_arg_limit_per_call )
out_arg_limit_per_call = OptoReg::add(warped,1);
! if (!RegMask::can_represent_arg(warped)) {
C->record_method_not_compilable_all_tiers("unsupported calling sequence");
return OptoReg::Bad;
}
return warped;
}
*** 1249,1259 ****
--- 1301,1311 ----
// Since the max-per-method covers the max-per-call-site and debug info
// is excluded on the max-per-method basis, debug info cannot land in
// this killed area.
uint r_cnt = mcall->tf()->range()->cnt();
MachProjNode *proj = new (C, 1) MachProjNode( mcall, r_cnt+10000, RegMask::Empty, MachProjNode::fat_proj );
! if (!RegMask::can_represent_arg(OptoReg::Name(out_arg_limit_per_call-1))) {
C->record_method_not_compilable_all_tiers("unsupported outgoing calling sequence");
} else {
for (int i = begin_out_arg_area; i < out_arg_limit_per_call; i++)
proj->_rout.Insert(OptoReg::Name(i));
}
src/share/vm/opto/matcher.cpp
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File