Path: blob/jdk8u272-b10-aarch32-20201026/hotspot/src/share/vm/adlc/formssel.cpp
48789 views
/*1* Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324// FORMS.CPP - Definitions for ADL Parser Forms Classes25#include "utilities/macros.hpp"26#include "adlc.hpp"2728//==============================Instructions===================================29//------------------------------InstructForm-----------------------------------30InstructForm::InstructForm(const char *id, bool ideal_only)31: _ident(id), _ideal_only(ideal_only),32_localNames(cmpstr, hashstr, Form::arena),33_effects(cmpstr, hashstr, Form::arena),34_is_mach_constant(false),35_needs_constant_base(false),36_has_call(false)37{38_ftype = Form::INS;3940_matrule = NULL;41_insencode = NULL;42_constant = NULL;43_is_postalloc_expand = false;44_opcode = NULL;45_size = NULL;46_attribs = NULL;47_predicate = NULL;48_exprule = NULL;49_rewrule = NULL;50_format = NULL;51_peephole = NULL;52_ins_pipe = NULL;53_uniq_idx = NULL;54_num_uniq = 0;55_cisc_spill_operand = Not_cisc_spillable;// Which operand may cisc-spill56_cisc_spill_alternate = NULL; // possible cisc replacement57_cisc_reg_mask_name = NULL;58_is_cisc_alternate = false;59_is_short_branch = false;60_short_branch_form = NULL;61_alignment = 1;62}6364InstructForm::InstructForm(const char *id, InstructForm *instr, MatchRule *rule)65: _ident(id), _ideal_only(false),66_localNames(instr->_localNames),67_effects(instr->_effects),68_is_mach_constant(false),69_needs_constant_base(false),70_has_call(false)71{72_ftype = Form::INS;7374_matrule = rule;75_insencode = instr->_insencode;76_constant = instr->_constant;77_is_postalloc_expand = instr->_is_postalloc_expand;78_opcode = instr->_opcode;79_size = instr->_size;80_attribs = instr->_attribs;81_predicate = instr->_predicate;82_exprule = instr->_exprule;83_rewrule = instr->_rewrule;84_format = instr->_format;85_peephole = instr->_peephole;86_ins_pipe = instr->_ins_pipe;87_uniq_idx = instr->_uniq_idx;88_num_uniq = instr->_num_uniq;89_cisc_spill_operand = Not_cisc_spillable; // Which operand may cisc-spill90_cisc_spill_alternate = NULL; // possible cisc replacement91_cisc_reg_mask_name = NULL;92_is_cisc_alternate = false;93_is_short_branch = false;94_short_branch_form = NULL;95_alignment = 1;96// Copy parameters97const char *name;98instr->_parameters.reset();99for (; (name = instr->_parameters.iter()) != NULL;)100_parameters.addName(name);101}102103InstructForm::~InstructForm() {104}105106InstructForm *InstructForm::is_instruction() const {107return (InstructForm*)this;108}109110bool InstructForm::ideal_only() const {111return _ideal_only;112}113114bool InstructForm::sets_result() const {115return (_matrule != NULL && _matrule->sets_result());116}117118bool InstructForm::needs_projections() {119_components.reset();120for( Component *comp; (comp = _components.iter()) != NULL; ) {121if (comp->isa(Component::KILL)) {122return true;123}124}125return false;126}127128129bool InstructForm::has_temps() {130if (_matrule) {131// Examine each component to see if it is a TEMP132_components.reset();133// Skip the first component, if already handled as (SET dst (...))134Component *comp = NULL;135if (sets_result()) comp = _components.iter();136while ((comp = _components.iter()) != NULL) {137if (comp->isa(Component::TEMP)) {138return true;139}140}141}142143return false;144}145146uint InstructForm::num_defs_or_kills() {147uint defs_or_kills = 0;148149_components.reset();150for( Component *comp; (comp = _components.iter()) != NULL; ) {151if( comp->isa(Component::DEF) || comp->isa(Component::KILL) ) {152++defs_or_kills;153}154}155156return defs_or_kills;157}158159// This instruction has an expand rule?160bool InstructForm::expands() const {161return ( _exprule != NULL );162}163164// This instruction has a late expand rule?165bool InstructForm::postalloc_expands() const {166return _is_postalloc_expand;167}168169// This instruction has a peephole rule?170Peephole *InstructForm::peepholes() const {171return _peephole;172}173174// This instruction has a peephole rule?175void InstructForm::append_peephole(Peephole *peephole) {176if( _peephole == NULL ) {177_peephole = peephole;178} else {179_peephole->append_peephole(peephole);180}181}182183184// ideal opcode enumeration185const char *InstructForm::ideal_Opcode( FormDict &globalNames ) const {186if( !_matrule ) return "Node"; // Something weird187// Chain rules do not really have ideal Opcodes; use their source188// operand ideal Opcode instead.189if( is_simple_chain_rule(globalNames) ) {190const char *src = _matrule->_rChild->_opType;191OperandForm *src_op = globalNames[src]->is_operand();192assert( src_op, "Not operand class of chain rule" );193if( !src_op->_matrule ) return "Node";194return src_op->_matrule->_opType;195}196// Operand chain rules do not really have ideal Opcodes197if( _matrule->is_chain_rule(globalNames) )198return "Node";199return strcmp(_matrule->_opType,"Set")200? _matrule->_opType201: _matrule->_rChild->_opType;202}203204// Recursive check on all operands' match rules in my match rule205bool InstructForm::is_pinned(FormDict &globals) {206if ( ! _matrule) return false;207208int index = 0;209if (_matrule->find_type("Goto", index)) return true;210if (_matrule->find_type("If", index)) return true;211if (_matrule->find_type("CountedLoopEnd",index)) return true;212if (_matrule->find_type("Return", index)) return true;213if (_matrule->find_type("Rethrow", index)) return true;214if (_matrule->find_type("TailCall", index)) return true;215if (_matrule->find_type("TailJump", index)) return true;216if (_matrule->find_type("Halt", index)) return true;217if (_matrule->find_type("Jump", index)) return true;218219return is_parm(globals);220}221222// Recursive check on all operands' match rules in my match rule223bool InstructForm::is_projection(FormDict &globals) {224if ( ! _matrule) return false;225226int index = 0;227if (_matrule->find_type("Goto", index)) return true;228if (_matrule->find_type("Return", index)) return true;229if (_matrule->find_type("Rethrow", index)) return true;230if (_matrule->find_type("TailCall",index)) return true;231if (_matrule->find_type("TailJump",index)) return true;232if (_matrule->find_type("Halt", index)) return true;233234return false;235}236237// Recursive check on all operands' match rules in my match rule238bool InstructForm::is_parm(FormDict &globals) {239if ( ! _matrule) return false;240241int index = 0;242if (_matrule->find_type("Parm",index)) return true;243244return false;245}246247bool InstructForm::is_ideal_negD() const {248return (_matrule && _matrule->_rChild && strcmp(_matrule->_rChild->_opType, "NegD") == 0);249}250251// Return 'true' if this instruction matches an ideal 'Copy*' node252int InstructForm::is_ideal_copy() const {253return _matrule ? _matrule->is_ideal_copy() : 0;254}255256// Return 'true' if this instruction is too complex to rematerialize.257int InstructForm::is_expensive() const {258// We can prove it is cheap if it has an empty encoding.259// This helps with platform-specific nops like ThreadLocal and RoundFloat.260if (is_empty_encoding())261return 0;262263if (is_tls_instruction())264return 1;265266if (_matrule == NULL) return 0;267268return _matrule->is_expensive();269}270271// Has an empty encoding if _size is a constant zero or there272// are no ins_encode tokens.273int InstructForm::is_empty_encoding() const {274if (_insencode != NULL) {275_insencode->reset();276if (_insencode->encode_class_iter() == NULL) {277return 1;278}279}280if (_size != NULL && strcmp(_size, "0") == 0) {281return 1;282}283return 0;284}285286int InstructForm::is_tls_instruction() const {287if (_ident != NULL &&288( ! strcmp( _ident,"tlsLoadP") ||289! strncmp(_ident,"tlsLoadP_",9)) ) {290return 1;291}292293if (_matrule != NULL && _insencode != NULL) {294const char* opType = _matrule->_opType;295if (strcmp(opType, "Set")==0)296opType = _matrule->_rChild->_opType;297if (strcmp(opType,"ThreadLocal")==0) {298fprintf(stderr, "Warning: ThreadLocal instruction %s should be named 'tlsLoadP_*'\n",299(_ident == NULL ? "NULL" : _ident));300return 1;301}302}303304return 0;305}306307308// Return 'true' if this instruction matches an ideal 'If' node309bool InstructForm::is_ideal_if() const {310if( _matrule == NULL ) return false;311312return _matrule->is_ideal_if();313}314315// Return 'true' if this instruction matches an ideal 'FastLock' node316bool InstructForm::is_ideal_fastlock() const {317if( _matrule == NULL ) return false;318319return _matrule->is_ideal_fastlock();320}321322// Return 'true' if this instruction matches an ideal 'MemBarXXX' node323bool InstructForm::is_ideal_membar() const {324if( _matrule == NULL ) return false;325326return _matrule->is_ideal_membar();327}328329// Return 'true' if this instruction matches an ideal 'LoadPC' node330bool InstructForm::is_ideal_loadPC() const {331if( _matrule == NULL ) return false;332333return _matrule->is_ideal_loadPC();334}335336// Return 'true' if this instruction matches an ideal 'Box' node337bool InstructForm::is_ideal_box() const {338if( _matrule == NULL ) return false;339340return _matrule->is_ideal_box();341}342343// Return 'true' if this instruction matches an ideal 'Goto' node344bool InstructForm::is_ideal_goto() const {345if( _matrule == NULL ) return false;346347return _matrule->is_ideal_goto();348}349350// Return 'true' if this instruction matches an ideal 'Jump' node351bool InstructForm::is_ideal_jump() const {352if( _matrule == NULL ) return false;353354return _matrule->is_ideal_jump();355}356357// Return 'true' if instruction matches ideal 'If' | 'Goto' | 'CountedLoopEnd'358bool InstructForm::is_ideal_branch() const {359if( _matrule == NULL ) return false;360361return _matrule->is_ideal_if() || _matrule->is_ideal_goto();362}363364365// Return 'true' if this instruction matches an ideal 'Return' node366bool InstructForm::is_ideal_return() const {367if( _matrule == NULL ) return false;368369// Check MatchRule to see if the first entry is the ideal "Return" node370int index = 0;371if (_matrule->find_type("Return",index)) return true;372if (_matrule->find_type("Rethrow",index)) return true;373if (_matrule->find_type("TailCall",index)) return true;374if (_matrule->find_type("TailJump",index)) return true;375376return false;377}378379// Return 'true' if this instruction matches an ideal 'Halt' node380bool InstructForm::is_ideal_halt() const {381int index = 0;382return _matrule && _matrule->find_type("Halt",index);383}384385// Return 'true' if this instruction matches an ideal 'SafePoint' node386bool InstructForm::is_ideal_safepoint() const {387int index = 0;388return _matrule && _matrule->find_type("SafePoint",index);389}390391// Return 'true' if this instruction matches an ideal 'Nop' node392bool InstructForm::is_ideal_nop() const {393return _ident && _ident[0] == 'N' && _ident[1] == 'o' && _ident[2] == 'p' && _ident[3] == '_';394}395396bool InstructForm::is_ideal_control() const {397if ( ! _matrule) return false;398399return is_ideal_return() || is_ideal_branch() || _matrule->is_ideal_jump() || is_ideal_halt();400}401402// Return 'true' if this instruction matches an ideal 'Call' node403Form::CallType InstructForm::is_ideal_call() const {404if( _matrule == NULL ) return Form::invalid_type;405406// Check MatchRule to see if the first entry is the ideal "Call" node407int idx = 0;408if(_matrule->find_type("CallStaticJava",idx)) return Form::JAVA_STATIC;409idx = 0;410if(_matrule->find_type("Lock",idx)) return Form::JAVA_STATIC;411idx = 0;412if(_matrule->find_type("Unlock",idx)) return Form::JAVA_STATIC;413idx = 0;414if(_matrule->find_type("CallDynamicJava",idx)) return Form::JAVA_DYNAMIC;415idx = 0;416if(_matrule->find_type("CallRuntime",idx)) return Form::JAVA_RUNTIME;417idx = 0;418if(_matrule->find_type("CallLeaf",idx)) return Form::JAVA_LEAF;419idx = 0;420if(_matrule->find_type("CallLeafNoFP",idx)) return Form::JAVA_LEAF;421idx = 0;422423return Form::invalid_type;424}425426// Return 'true' if this instruction matches an ideal 'Load?' node427Form::DataType InstructForm::is_ideal_load() const {428if( _matrule == NULL ) return Form::none;429430return _matrule->is_ideal_load();431}432433// Return 'true' if this instruction matches an ideal 'LoadKlass' node434bool InstructForm::skip_antidep_check() const {435if( _matrule == NULL ) return false;436437return _matrule->skip_antidep_check();438}439440// Return 'true' if this instruction matches an ideal 'Load?' node441Form::DataType InstructForm::is_ideal_store() const {442if( _matrule == NULL ) return Form::none;443444return _matrule->is_ideal_store();445}446447// Return 'true' if this instruction matches an ideal vector node448bool InstructForm::is_vector() const {449if( _matrule == NULL ) return false;450451return _matrule->is_vector();452}453454455// Return the input register that must match the output register456// If this is not required, return 0457uint InstructForm::two_address(FormDict &globals) {458uint matching_input = 0;459if(_components.count() == 0) return 0;460461_components.reset();462Component *comp = _components.iter();463// Check if there is a DEF464if( comp->isa(Component::DEF) ) {465// Check that this is a register466const char *def_type = comp->_type;467const Form *form = globals[def_type];468OperandForm *op = form->is_operand();469if( op ) {470if( op->constrained_reg_class() != NULL &&471op->interface_type(globals) == Form::register_interface ) {472// Remember the local name for equality test later473const char *def_name = comp->_name;474// Check if a component has the same name and is a USE475do {476if( comp->isa(Component::USE) && strcmp(comp->_name,def_name)==0 ) {477return operand_position_format(def_name);478}479} while( (comp = _components.iter()) != NULL);480}481}482}483484return 0;485}486487488// when chaining a constant to an instruction, returns 'true' and sets opType489Form::DataType InstructForm::is_chain_of_constant(FormDict &globals) {490const char *dummy = NULL;491const char *dummy2 = NULL;492return is_chain_of_constant(globals, dummy, dummy2);493}494Form::DataType InstructForm::is_chain_of_constant(FormDict &globals,495const char * &opTypeParam) {496const char *result = NULL;497498return is_chain_of_constant(globals, opTypeParam, result);499}500501Form::DataType InstructForm::is_chain_of_constant(FormDict &globals,502const char * &opTypeParam, const char * &resultParam) {503Form::DataType data_type = Form::none;504if ( ! _matrule) return data_type;505506// !!!!!507// The source of the chain rule is 'position = 1'508uint position = 1;509const char *result = NULL;510const char *name = NULL;511const char *opType = NULL;512// Here base_operand is looking for an ideal type to be returned (opType).513if ( _matrule->is_chain_rule(globals)514&& _matrule->base_operand(position, globals, result, name, opType) ) {515data_type = ideal_to_const_type(opType);516517// if it isn't an ideal constant type, just return518if ( data_type == Form::none ) return data_type;519520// Ideal constant types also adjust the opType parameter.521resultParam = result;522opTypeParam = opType;523return data_type;524}525526return data_type;527}528529// Check if a simple chain rule530bool InstructForm::is_simple_chain_rule(FormDict &globals) const {531if( _matrule && _matrule->sets_result()532&& _matrule->_rChild->_lChild == NULL533&& globals[_matrule->_rChild->_opType]534&& globals[_matrule->_rChild->_opType]->is_opclass() ) {535return true;536}537return false;538}539540// check for structural rematerialization541bool InstructForm::rematerialize(FormDict &globals, RegisterForm *registers ) {542bool rematerialize = false;543544Form::DataType data_type = is_chain_of_constant(globals);545if( data_type != Form::none )546rematerialize = true;547548// Constants549if( _components.count() == 1 && _components[0]->is(Component::USE_DEF) )550rematerialize = true;551552// Pseudo-constants (values easily available to the runtime)553if (is_empty_encoding() && is_tls_instruction())554rematerialize = true;555556// 1-input, 1-output, such as copies or increments.557if( _components.count() == 2 &&558_components[0]->is(Component::DEF) &&559_components[1]->isa(Component::USE) )560rematerialize = true;561562// Check for an ideal 'Load?' and eliminate rematerialize option563if ( is_ideal_load() != Form::none || // Ideal load? Do not rematerialize564is_ideal_copy() != Form::none || // Ideal copy? Do not rematerialize565is_expensive() != Form::none) { // Expensive? Do not rematerialize566rematerialize = false;567}568569// Always rematerialize the flags. They are more expensive to save &570// restore than to recompute (and possibly spill the compare's inputs).571if( _components.count() >= 1 ) {572Component *c = _components[0];573const Form *form = globals[c->_type];574OperandForm *opform = form->is_operand();575if( opform ) {576// Avoid the special stack_slots register classes577const char *rc_name = opform->constrained_reg_class();578if( rc_name ) {579if( strcmp(rc_name,"stack_slots") ) {580// Check for ideal_type of RegFlags581const char *type = opform->ideal_type( globals, registers );582if( (type != NULL) && !strcmp(type, "RegFlags") )583rematerialize = true;584} else585rematerialize = false; // Do not rematerialize things target stk586}587}588}589590return rematerialize;591}592593// loads from memory, so must check for anti-dependence594bool InstructForm::needs_anti_dependence_check(FormDict &globals) const {595if ( skip_antidep_check() ) return false;596597// Machine independent loads must be checked for anti-dependences598if( is_ideal_load() != Form::none ) return true;599600// !!!!! !!!!! !!!!!601// TEMPORARY602// if( is_simple_chain_rule(globals) ) return false;603604// String.(compareTo/equals/indexOf) and Arrays.equals use many memorys edges,605// but writes none606if( _matrule && _matrule->_rChild &&607( strcmp(_matrule->_rChild->_opType,"StrComp" )==0 ||608strcmp(_matrule->_rChild->_opType,"StrEquals" )==0 ||609strcmp(_matrule->_rChild->_opType,"StrIndexOf" )==0 ||610strcmp(_matrule->_rChild->_opType,"AryEq" )==0 ))611return true;612613// Check if instruction has a USE of a memory operand class, but no defs614bool USE_of_memory = false;615bool DEF_of_memory = false;616Component *comp = NULL;617ComponentList &components = (ComponentList &)_components;618619components.reset();620while( (comp = components.iter()) != NULL ) {621const Form *form = globals[comp->_type];622if( !form ) continue;623OpClassForm *op = form->is_opclass();624if( !op ) continue;625if( form->interface_type(globals) == Form::memory_interface ) {626if( comp->isa(Component::USE) ) USE_of_memory = true;627if( comp->isa(Component::DEF) ) {628OperandForm *oper = form->is_operand();629if( oper && oper->is_user_name_for_sReg() ) {630// Stack slots are unaliased memory handled by allocator631oper = oper; // debug stopping point !!!!!632} else {633DEF_of_memory = true;634}635}636}637}638return (USE_of_memory && !DEF_of_memory);639}640641642bool InstructForm::is_wide_memory_kill(FormDict &globals) const {643if( _matrule == NULL ) return false;644if( !_matrule->_opType ) return false;645646if( strcmp(_matrule->_opType,"MemBarRelease") == 0 ) return true;647if( strcmp(_matrule->_opType,"MemBarAcquire") == 0 ) return true;648if( strcmp(_matrule->_opType,"MemBarReleaseLock") == 0 ) return true;649if( strcmp(_matrule->_opType,"MemBarAcquireLock") == 0 ) return true;650if( strcmp(_matrule->_opType,"MemBarStoreStore") == 0 ) return true;651if( strcmp(_matrule->_opType,"MemBarVolatile") == 0 ) return true;652if( strcmp(_matrule->_opType,"StoreFence") == 0 ) return true;653if( strcmp(_matrule->_opType,"LoadFence") == 0 ) return true;654655return false;656}657658int InstructForm::memory_operand(FormDict &globals) const {659// Machine independent loads must be checked for anti-dependences660// Check if instruction has a USE of a memory operand class, or a def.661int USE_of_memory = 0;662int DEF_of_memory = 0;663const char* last_memory_DEF = NULL; // to test DEF/USE pairing in asserts664const char* last_memory_USE = NULL;665Component *unique = NULL;666Component *comp = NULL;667ComponentList &components = (ComponentList &)_components;668669components.reset();670while( (comp = components.iter()) != NULL ) {671const Form *form = globals[comp->_type];672if( !form ) continue;673OpClassForm *op = form->is_opclass();674if( !op ) continue;675if( op->stack_slots_only(globals) ) continue;676if( form->interface_type(globals) == Form::memory_interface ) {677if( comp->isa(Component::DEF) ) {678last_memory_DEF = comp->_name;679DEF_of_memory++;680unique = comp;681} else if( comp->isa(Component::USE) ) {682if( last_memory_DEF != NULL ) {683assert(0 == strcmp(last_memory_DEF, comp->_name), "every memory DEF is followed by a USE of the same name");684last_memory_DEF = NULL;685}686// Handles same memory being used multiple times in the case of BMI1 instructions.687if (last_memory_USE != NULL) {688if (strcmp(comp->_name, last_memory_USE) != 0) {689USE_of_memory++;690}691} else {692USE_of_memory++;693}694last_memory_USE = comp->_name;695696if (DEF_of_memory == 0) // defs take precedence697unique = comp;698} else {699assert(last_memory_DEF == NULL, "unpaired memory DEF");700}701}702}703assert(last_memory_DEF == NULL, "unpaired memory DEF");704assert(USE_of_memory >= DEF_of_memory, "unpaired memory DEF");705USE_of_memory -= DEF_of_memory; // treat paired DEF/USE as one occurrence706if( (USE_of_memory + DEF_of_memory) > 0 ) {707if( is_simple_chain_rule(globals) ) {708//fprintf(stderr, "Warning: chain rule is not really a memory user.\n");709//((InstructForm*)this)->dump();710// Preceding code prints nothing on sparc and these insns on intel:711// leaP8 leaP32 leaPIdxOff leaPIdxScale leaPIdxScaleOff leaP8 leaP32712// leaPIdxOff leaPIdxScale leaPIdxScaleOff713return NO_MEMORY_OPERAND;714}715716if( DEF_of_memory == 1 ) {717assert(unique != NULL, "");718if( USE_of_memory == 0 ) {719// unique def, no uses720} else {721// // unique def, some uses722// // must return bottom unless all uses match def723// unique = NULL;724}725} else if( DEF_of_memory > 0 ) {726// multiple defs, don't care about uses727unique = NULL;728} else if( USE_of_memory == 1) {729// unique use, no defs730assert(unique != NULL, "");731} else if( USE_of_memory > 0 ) {732// multiple uses, no defs733unique = NULL;734} else {735assert(false, "bad case analysis");736}737// process the unique DEF or USE, if there is one738if( unique == NULL ) {739return MANY_MEMORY_OPERANDS;740} else {741int pos = components.operand_position(unique->_name);742if( unique->isa(Component::DEF) ) {743pos += 1; // get corresponding USE from DEF744}745assert(pos >= 1, "I was just looking at it!");746return pos;747}748}749750// missed the memory op??751if( true ) { // %%% should not be necessary752if( is_ideal_store() != Form::none ) {753fprintf(stderr, "Warning: cannot find memory opnd in instr.\n");754((InstructForm*)this)->dump();755// pretend it has multiple defs and uses756return MANY_MEMORY_OPERANDS;757}758if( is_ideal_load() != Form::none ) {759fprintf(stderr, "Warning: cannot find memory opnd in instr.\n");760((InstructForm*)this)->dump();761// pretend it has multiple uses and no defs762return MANY_MEMORY_OPERANDS;763}764}765766return NO_MEMORY_OPERAND;767}768769770// This instruction captures the machine-independent bottom_type771// Expected use is for pointer vs oop determination for LoadP772bool InstructForm::captures_bottom_type(FormDict &globals) const {773if( _matrule && _matrule->_rChild &&774(!strcmp(_matrule->_rChild->_opType,"CastPP") || // new result type775!strcmp(_matrule->_rChild->_opType,"CastX2P") || // new result type776!strcmp(_matrule->_rChild->_opType,"DecodeN") ||777!strcmp(_matrule->_rChild->_opType,"EncodeP") ||778!strcmp(_matrule->_rChild->_opType,"DecodeNKlass") ||779!strcmp(_matrule->_rChild->_opType,"EncodePKlass") ||780!strcmp(_matrule->_rChild->_opType,"LoadN") ||781!strcmp(_matrule->_rChild->_opType,"LoadNKlass") ||782!strcmp(_matrule->_rChild->_opType,"CreateEx") || // type of exception783!strcmp(_matrule->_rChild->_opType,"CheckCastPP") ||784!strcmp(_matrule->_rChild->_opType,"GetAndSetP") ||785!strcmp(_matrule->_rChild->_opType,"GetAndSetN")) ) return true;786else if ( is_ideal_load() == Form::idealP ) return true;787else if ( is_ideal_store() != Form::none ) return true;788789if (needs_base_oop_edge(globals)) return true;790791if (is_vector()) return true;792if (is_mach_constant()) return true;793794return false;795}796797798// Access instr_cost attribute or return NULL.799const char* InstructForm::cost() {800for (Attribute* cur = _attribs; cur != NULL; cur = (Attribute*)cur->_next) {801if( strcmp(cur->_ident,AttributeForm::_ins_cost) == 0 ) {802return cur->_val;803}804}805return NULL;806}807808// Return count of top-level operands.809uint InstructForm::num_opnds() {810int num_opnds = _components.num_operands();811812// Need special handling for matching some ideal nodes813// i.e. Matching a return node814/*815if( _matrule ) {816if( strcmp(_matrule->_opType,"Return" )==0 ||817strcmp(_matrule->_opType,"Halt" )==0 )818return 3;819}820*/821return num_opnds;822}823824const char* InstructForm::opnd_ident(int idx) {825return _components.at(idx)->_name;826}827828const char* InstructForm::unique_opnd_ident(uint idx) {829uint i;830for (i = 1; i < num_opnds(); ++i) {831if (unique_opnds_idx(i) == idx) {832break;833}834}835return (_components.at(i) != NULL) ? _components.at(i)->_name : "";836}837838// Return count of unmatched operands.839uint InstructForm::num_post_match_opnds() {840uint num_post_match_opnds = _components.count();841uint num_match_opnds = _components.match_count();842num_post_match_opnds = num_post_match_opnds - num_match_opnds;843844return num_post_match_opnds;845}846847// Return the number of leaves below this complex operand848uint InstructForm::num_consts(FormDict &globals) const {849if ( ! _matrule) return 0;850851// This is a recursive invocation on all operands in the matchrule852return _matrule->num_consts(globals);853}854855// Constants in match rule with specified type856uint InstructForm::num_consts(FormDict &globals, Form::DataType type) const {857if ( ! _matrule) return 0;858859// This is a recursive invocation on all operands in the matchrule860return _matrule->num_consts(globals, type);861}862863864// Return the register class associated with 'leaf'.865const char *InstructForm::out_reg_class(FormDict &globals) {866assert( false, "InstructForm::out_reg_class(FormDict &globals); Not Implemented");867868return NULL;869}870871872873// Lookup the starting position of inputs we are interested in wrt. ideal nodes874uint InstructForm::oper_input_base(FormDict &globals) {875if( !_matrule ) return 1; // Skip control for most nodes876877// Need special handling for matching some ideal nodes878// i.e. Matching a return node879if( strcmp(_matrule->_opType,"Return" )==0 ||880strcmp(_matrule->_opType,"Rethrow" )==0 ||881strcmp(_matrule->_opType,"TailCall" )==0 ||882strcmp(_matrule->_opType,"TailJump" )==0 ||883strcmp(_matrule->_opType,"SafePoint" )==0 ||884strcmp(_matrule->_opType,"Halt" )==0 )885return AdlcVMDeps::Parms; // Skip the machine-state edges886887if( _matrule->_rChild &&888( strcmp(_matrule->_rChild->_opType,"AryEq" )==0 ||889strcmp(_matrule->_rChild->_opType,"StrComp" )==0 ||890strcmp(_matrule->_rChild->_opType,"StrEquals" )==0 ||891strcmp(_matrule->_rChild->_opType,"StrIndexOf")==0 ||892strcmp(_matrule->_rChild->_opType,"EncodeISOArray")==0)) {893// String.(compareTo/equals/indexOf) and Arrays.equals894// and sun.nio.cs.iso8859_1$Encoder.EncodeISOArray895// take 1 control and 1 memory edges.896return 2;897}898899// Check for handling of 'Memory' input/edge in the ideal world.900// The AD file writer is shielded from knowledge of these edges.901int base = 1; // Skip control902base += _matrule->needs_ideal_memory_edge(globals);903904// Also skip the base-oop value for uses of derived oops.905// The AD file writer is shielded from knowledge of these edges.906base += needs_base_oop_edge(globals);907908return base;909}910911// This function determines the order of the MachOper in _opnds[]912// by writing the operand names into the _components list.913//914// Implementation does not modify state of internal structures915void InstructForm::build_components() {916// Add top-level operands to the components917if (_matrule) _matrule->append_components(_localNames, _components);918919// Add parameters that "do not appear in match rule".920bool has_temp = false;921const char *name;922const char *kill_name = NULL;923for (_parameters.reset(); (name = _parameters.iter()) != NULL;) {924OpClassForm *opForm = _localNames[name]->is_opclass();925assert(opForm != NULL, "sanity");926927Effect* e = NULL;928{929const Form* form = _effects[name];930e = form ? form->is_effect() : NULL;931}932933if (e != NULL) {934has_temp |= e->is(Component::TEMP);935936// KILLs must be declared after any TEMPs because TEMPs are real937// uses so their operand numbering must directly follow the real938// inputs from the match rule. Fixing the numbering seems939// complex so simply enforce the restriction during parse.940if (kill_name != NULL &&941e->isa(Component::TEMP) && !e->isa(Component::DEF)) {942OpClassForm* kill = _localNames[kill_name]->is_opclass();943assert(kill != NULL, "sanity");944globalAD->syntax_err(_linenum, "%s: %s %s must be at the end of the argument list\n",945_ident, kill->_ident, kill_name);946} else if (e->isa(Component::KILL) && !e->isa(Component::USE)) {947kill_name = name;948}949}950951const Component *component = _components.search(name);952if ( component == NULL ) {953if (e) {954_components.insert(name, opForm->_ident, e->_use_def, false);955component = _components.search(name);956if (component->isa(Component::USE) && !component->isa(Component::TEMP) && _matrule) {957const Form *form = globalAD->globalNames()[component->_type];958assert( form, "component type must be a defined form");959OperandForm *op = form->is_operand();960if (op->_interface && op->_interface->is_RegInterface()) {961globalAD->syntax_err(_linenum, "%s: illegal USE of non-input: %s %s\n",962_ident, opForm->_ident, name);963}964}965} else {966// This would be a nice warning but it triggers in a few places in a benign way967// if (_matrule != NULL && !expands()) {968// globalAD->syntax_err(_linenum, "%s: %s %s not mentioned in effect or match rule\n",969// _ident, opForm->_ident, name);970// }971_components.insert(name, opForm->_ident, Component::INVALID, false);972}973}974else if (e) {975// Component was found in the list976// Check if there is a new effect that requires an extra component.977// This happens when adding 'USE' to a component that is not yet one.978if ((!component->isa( Component::USE) && ((e->_use_def & Component::USE) != 0))) {979if (component->isa(Component::USE) && _matrule) {980const Form *form = globalAD->globalNames()[component->_type];981assert( form, "component type must be a defined form");982OperandForm *op = form->is_operand();983if (op->_interface && op->_interface->is_RegInterface()) {984globalAD->syntax_err(_linenum, "%s: illegal USE of non-input: %s %s\n",985_ident, opForm->_ident, name);986}987}988_components.insert(name, opForm->_ident, e->_use_def, false);989} else {990Component *comp = (Component*)component;991comp->promote_use_def_info(e->_use_def);992}993// Component positions are zero based.994int pos = _components.operand_position(name);995assert( ! (component->isa(Component::DEF) && (pos >= 1)),996"Component::DEF can only occur in the first position");997}998}9991000// Resolving the interactions between expand rules and TEMPs would1001// be complex so simply disallow it.1002if (_matrule == NULL && has_temp) {1003globalAD->syntax_err(_linenum, "%s: TEMPs without match rule isn't supported\n", _ident);1004}10051006return;1007}10081009// Return zero-based position in component list; -1 if not in list.1010int InstructForm::operand_position(const char *name, int usedef) {1011return unique_opnds_idx(_components.operand_position(name, usedef, this));1012}10131014int InstructForm::operand_position_format(const char *name) {1015return unique_opnds_idx(_components.operand_position_format(name, this));1016}10171018// Return zero-based position in component list; -1 if not in list.1019int InstructForm::label_position() {1020return unique_opnds_idx(_components.label_position());1021}10221023int InstructForm::method_position() {1024return unique_opnds_idx(_components.method_position());1025}10261027// Return number of relocation entries needed for this instruction.1028uint InstructForm::reloc(FormDict &globals) {1029uint reloc_entries = 0;1030// Check for "Call" nodes1031if ( is_ideal_call() ) ++reloc_entries;1032if ( is_ideal_return() ) ++reloc_entries;1033if ( is_ideal_safepoint() ) ++reloc_entries;103410351036// Check if operands MAYBE oop pointers, by checking for ConP elements1037// Proceed through the leaves of the match-tree and check for ConPs1038if ( _matrule != NULL ) {1039uint position = 0;1040const char *result = NULL;1041const char *name = NULL;1042const char *opType = NULL;1043while (_matrule->base_operand(position, globals, result, name, opType)) {1044if ( strcmp(opType,"ConP") == 0 ) {1045#ifdef SPARC1046reloc_entries += 2; // 1 for sethi + 1 for setlo1047#else1048++reloc_entries;1049#endif1050}1051++position;1052}1053}10541055// Above is only a conservative estimate1056// because it did not check contents of operand classes.1057// !!!!! !!!!!1058// Add 1 to reloc info for each operand class in the component list.1059Component *comp;1060_components.reset();1061while ( (comp = _components.iter()) != NULL ) {1062const Form *form = globals[comp->_type];1063assert( form, "Did not find component's type in global names");1064const OpClassForm *opc = form->is_opclass();1065const OperandForm *oper = form->is_operand();1066if ( opc && (oper == NULL) ) {1067++reloc_entries;1068} else if ( oper ) {1069// floats and doubles loaded out of method's constant pool require reloc info1070Form::DataType type = oper->is_base_constant(globals);1071if ( (type == Form::idealF) || (type == Form::idealD) ) {1072++reloc_entries;1073}1074}1075}10761077// Float and Double constants may come from the CodeBuffer table1078// and require relocatable addresses for access1079// !!!!!1080// Check for any component being an immediate float or double.1081Form::DataType data_type = is_chain_of_constant(globals);1082if( data_type==idealD || data_type==idealF ) {1083#ifdef SPARC1084// sparc required more relocation entries for floating constants1085// (expires 9/98)1086reloc_entries += 6;1087#else1088reloc_entries++;1089#endif1090}10911092return reloc_entries;1093}10941095// Utility function defined in archDesc.cpp1096extern bool is_def(int usedef);10971098// Return the result of reducing an instruction1099const char *InstructForm::reduce_result() {1100const char* result = "Universe"; // default1101_components.reset();1102Component *comp = _components.iter();1103if (comp != NULL && comp->isa(Component::DEF)) {1104result = comp->_type;1105// Override this if the rule is a store operation:1106if (_matrule && _matrule->_rChild &&1107is_store_to_memory(_matrule->_rChild->_opType))1108result = "Universe";1109}1110return result;1111}11121113// Return the name of the operand on the right hand side of the binary match1114// Return NULL if there is no right hand side1115const char *InstructForm::reduce_right(FormDict &globals) const {1116if( _matrule == NULL ) return NULL;1117return _matrule->reduce_right(globals);1118}11191120// Similar for left1121const char *InstructForm::reduce_left(FormDict &globals) const {1122if( _matrule == NULL ) return NULL;1123return _matrule->reduce_left(globals);1124}112511261127// Base class for this instruction, MachNode except for calls1128const char *InstructForm::mach_base_class(FormDict &globals) const {1129if( is_ideal_call() == Form::JAVA_STATIC ) {1130return "MachCallStaticJavaNode";1131}1132else if( is_ideal_call() == Form::JAVA_DYNAMIC ) {1133return "MachCallDynamicJavaNode";1134}1135else if( is_ideal_call() == Form::JAVA_RUNTIME ) {1136return "MachCallRuntimeNode";1137}1138else if( is_ideal_call() == Form::JAVA_LEAF ) {1139return "MachCallLeafNode";1140}1141else if (is_ideal_return()) {1142return "MachReturnNode";1143}1144else if (is_ideal_halt()) {1145return "MachHaltNode";1146}1147else if (is_ideal_safepoint()) {1148return "MachSafePointNode";1149}1150else if (is_ideal_if()) {1151return "MachIfNode";1152}1153else if (is_ideal_goto()) {1154return "MachGotoNode";1155}1156else if (is_ideal_fastlock()) {1157return "MachFastLockNode";1158}1159else if (is_ideal_nop()) {1160return "MachNopNode";1161}1162else if (is_mach_constant()) {1163return "MachConstantNode";1164}1165else if (captures_bottom_type(globals)) {1166return "MachTypeNode";1167} else {1168return "MachNode";1169}1170assert( false, "ShouldNotReachHere()");1171return NULL;1172}11731174// Compare the instruction predicates for textual equality1175bool equivalent_predicates( const InstructForm *instr1, const InstructForm *instr2 ) {1176const Predicate *pred1 = instr1->_predicate;1177const Predicate *pred2 = instr2->_predicate;1178if( pred1 == NULL && pred2 == NULL ) {1179// no predicates means they are identical1180return true;1181}1182if( pred1 != NULL && pred2 != NULL ) {1183// compare the predicates1184if (ADLParser::equivalent_expressions(pred1->_pred, pred2->_pred)) {1185return true;1186}1187}11881189return false;1190}11911192// Check if this instruction can cisc-spill to 'alternate'1193bool InstructForm::cisc_spills_to(ArchDesc &AD, InstructForm *instr) {1194assert( _matrule != NULL && instr->_matrule != NULL, "must have match rules");1195// Do not replace if a cisc-version has been found.1196if( cisc_spill_operand() != Not_cisc_spillable ) return false;11971198int cisc_spill_operand = Maybe_cisc_spillable;1199char *result = NULL;1200char *result2 = NULL;1201const char *op_name = NULL;1202const char *reg_type = NULL;1203FormDict &globals = AD.globalNames();1204cisc_spill_operand = _matrule->matchrule_cisc_spill_match(globals, AD.get_registers(), instr->_matrule, op_name, reg_type);1205if( (cisc_spill_operand != Not_cisc_spillable) && (op_name != NULL) && equivalent_predicates(this, instr) ) {1206cisc_spill_operand = operand_position(op_name, Component::USE);1207int def_oper = operand_position(op_name, Component::DEF);1208if( def_oper == NameList::Not_in_list && instr->num_opnds() == num_opnds()) {1209// Do not support cisc-spilling for destination operands and1210// make sure they have the same number of operands.1211_cisc_spill_alternate = instr;1212instr->set_cisc_alternate(true);1213if( AD._cisc_spill_debug ) {1214fprintf(stderr, "Instruction %s cisc-spills-to %s\n", _ident, instr->_ident);1215fprintf(stderr, " using operand %s %s at index %d\n", reg_type, op_name, cisc_spill_operand);1216}1217// Record that a stack-version of the reg_mask is needed1218// !!!!!1219OperandForm *oper = (OperandForm*)(globals[reg_type]->is_operand());1220assert( oper != NULL, "cisc-spilling non operand");1221const char *reg_class_name = oper->constrained_reg_class();1222AD.set_stack_or_reg(reg_class_name);1223const char *reg_mask_name = AD.reg_mask(*oper);1224set_cisc_reg_mask_name(reg_mask_name);1225const char *stack_or_reg_mask_name = AD.stack_or_reg_mask(*oper);1226} else {1227cisc_spill_operand = Not_cisc_spillable;1228}1229} else {1230cisc_spill_operand = Not_cisc_spillable;1231}12321233set_cisc_spill_operand(cisc_spill_operand);1234return (cisc_spill_operand != Not_cisc_spillable);1235}12361237// Check to see if this instruction can be replaced with the short branch1238// instruction `short-branch'1239bool InstructForm::check_branch_variant(ArchDesc &AD, InstructForm *short_branch) {1240if (_matrule != NULL &&1241this != short_branch && // Don't match myself1242!is_short_branch() && // Don't match another short branch variant1243reduce_result() != NULL &&1244strcmp(reduce_result(), short_branch->reduce_result()) == 0 &&1245_matrule->equivalent(AD.globalNames(), short_branch->_matrule)1246AARCH64_ONLY(&& equivalent_predicates(this, short_branch))) {1247// The instructions are equivalent.12481249// Now verify that both instructions have the same parameters and1250// the same effects. Both branch forms should have the same inputs1251// and resulting projections to correctly replace a long branch node1252// with corresponding short branch node during code generation.12531254bool different = false;1255if (short_branch->_components.count() != _components.count()) {1256different = true;1257} else if (_components.count() > 0) {1258short_branch->_components.reset();1259_components.reset();1260Component *comp;1261while ((comp = _components.iter()) != NULL) {1262Component *short_comp = short_branch->_components.iter();1263if (short_comp == NULL ||1264short_comp->_type != comp->_type ||1265short_comp->_usedef != comp->_usedef) {1266different = true;1267break;1268}1269}1270if (short_branch->_components.iter() != NULL)1271different = true;1272}1273if (different) {1274globalAD->syntax_err(short_branch->_linenum, "Instruction %s and its short form %s have different parameters\n", _ident, short_branch->_ident);1275}1276if (AD._adl_debug > 1 || AD._short_branch_debug) {1277fprintf(stderr, "Instruction %s has short form %s\n", _ident, short_branch->_ident);1278}1279_short_branch_form = short_branch;1280return true;1281}1282return false;1283}128412851286// --------------------------- FILE *output_routines1287//1288// Generate the format call for the replacement variable1289void InstructForm::rep_var_format(FILE *fp, const char *rep_var) {1290// Handle special constant table variables.1291if (strcmp(rep_var, "constanttablebase") == 0) {1292fprintf(fp, "char reg[128]; ra->dump_register(in(mach_constant_base_node_input()), reg);\n");1293fprintf(fp, " st->print(\"%%s\", reg);\n");1294return;1295}1296if (strcmp(rep_var, "constantoffset") == 0) {1297fprintf(fp, "st->print(\"#%%d\", constant_offset_unchecked());\n");1298return;1299}1300if (strcmp(rep_var, "constantaddress") == 0) {1301fprintf(fp, "st->print(\"constant table base + #%%d\", constant_offset_unchecked());\n");1302return;1303}13041305// Find replacement variable's type1306const Form *form = _localNames[rep_var];1307if (form == NULL) {1308globalAD->syntax_err(_linenum, "Unknown replacement variable %s in format statement of %s.",1309rep_var, _ident);1310return;1311}1312OpClassForm *opc = form->is_opclass();1313assert( opc, "replacement variable was not found in local names");1314// Lookup the index position of the replacement variable1315int idx = operand_position_format(rep_var);1316if ( idx == -1 ) {1317globalAD->syntax_err(_linenum, "Could not find replacement variable %s in format statement of %s.\n",1318rep_var, _ident);1319assert(strcmp(opc->_ident, "label") == 0, "Unimplemented");1320return;1321}13221323if (is_noninput_operand(idx)) {1324// This component isn't in the input array. Print out the static1325// name of the register.1326OperandForm* oper = form->is_operand();1327if (oper != NULL && oper->is_bound_register()) {1328const RegDef* first = oper->get_RegClass()->find_first_elem();1329fprintf(fp, " st->print_raw(\"%s\");\n", first->_regname);1330} else {1331globalAD->syntax_err(_linenum, "In %s can't find format for %s %s", _ident, opc->_ident, rep_var);1332}1333} else {1334// Output the format call for this operand1335fprintf(fp,"opnd_array(%d)->",idx);1336if (idx == 0)1337fprintf(fp,"int_format(ra, this, st); // %s\n", rep_var);1338else1339fprintf(fp,"ext_format(ra, this,idx%d, st); // %s\n", idx, rep_var );1340}1341}13421343// Seach through operands to determine parameters unique positions.1344void InstructForm::set_unique_opnds() {1345uint* uniq_idx = NULL;1346uint nopnds = num_opnds();1347uint num_uniq = nopnds;1348uint i;1349_uniq_idx_length = 0;1350if (nopnds > 0) {1351// Allocate index array. Worst case we're mapping from each1352// component back to an index and any DEF always goes at 0 so the1353// length of the array has to be the number of components + 1.1354_uniq_idx_length = _components.count() + 1;1355uniq_idx = (uint*) malloc(sizeof(uint) * _uniq_idx_length);1356for (i = 0; i < _uniq_idx_length; i++) {1357uniq_idx[i] = i;1358}1359}1360// Do it only if there is a match rule and no expand rule. With an1361// expand rule it is done by creating new mach node in Expand()1362// method.1363if (nopnds > 0 && _matrule != NULL && _exprule == NULL) {1364const char *name;1365uint count;1366bool has_dupl_use = false;13671368_parameters.reset();1369while ((name = _parameters.iter()) != NULL) {1370count = 0;1371uint position = 0;1372uint uniq_position = 0;1373_components.reset();1374Component *comp = NULL;1375if (sets_result()) {1376comp = _components.iter();1377position++;1378}1379// The next code is copied from the method operand_position().1380for (; (comp = _components.iter()) != NULL; ++position) {1381// When the first component is not a DEF,1382// leave space for the result operand!1383if (position==0 && (!comp->isa(Component::DEF))) {1384++position;1385}1386if (strcmp(name, comp->_name) == 0) {1387if (++count > 1) {1388assert(position < _uniq_idx_length, "out of bounds");1389uniq_idx[position] = uniq_position;1390has_dupl_use = true;1391} else {1392uniq_position = position;1393}1394}1395if (comp->isa(Component::DEF) && comp->isa(Component::USE)) {1396++position;1397if (position != 1)1398--position; // only use two slots for the 1st USE_DEF1399}1400}1401}1402if (has_dupl_use) {1403for (i = 1; i < nopnds; i++) {1404if (i != uniq_idx[i]) {1405break;1406}1407}1408uint j = i;1409for (; i < nopnds; i++) {1410if (i == uniq_idx[i]) {1411uniq_idx[i] = j++;1412}1413}1414num_uniq = j;1415}1416}1417_uniq_idx = uniq_idx;1418_num_uniq = num_uniq;1419}14201421// Generate index values needed for determining the operand position1422void InstructForm::index_temps(FILE *fp, FormDict &globals, const char *prefix, const char *receiver) {1423uint idx = 0; // position of operand in match rule1424int cur_num_opnds = num_opnds();14251426// Compute the index into vector of operand pointers:1427// idx0=0 is used to indicate that info comes from this same node, not from input edge.1428// idx1 starts at oper_input_base()1429if ( cur_num_opnds >= 1 ) {1430fprintf(fp," // Start at oper_input_base() and count operands\n");1431fprintf(fp," unsigned %sidx0 = %d;\n", prefix, oper_input_base(globals));1432fprintf(fp," unsigned %sidx1 = %d;", prefix, oper_input_base(globals));1433fprintf(fp," \t// %s\n", unique_opnd_ident(1));14341435// Generate starting points for other unique operands if they exist1436for ( idx = 2; idx < num_unique_opnds(); ++idx ) {1437if( *receiver == 0 ) {1438fprintf(fp," unsigned %sidx%d = %sidx%d + opnd_array(%d)->num_edges();",1439prefix, idx, prefix, idx-1, idx-1 );1440} else {1441fprintf(fp," unsigned %sidx%d = %sidx%d + %s_opnds[%d]->num_edges();",1442prefix, idx, prefix, idx-1, receiver, idx-1 );1443}1444fprintf(fp," \t// %s\n", unique_opnd_ident(idx));1445}1446}1447if( *receiver != 0 ) {1448// This value is used by generate_peepreplace when copying a node.1449// Don't emit it in other cases since it can hide bugs with the1450// use invalid idx's.1451fprintf(fp," unsigned %sidx%d = %sreq(); \n", prefix, idx, receiver);1452}14531454}14551456// ---------------------------1457bool InstructForm::verify() {1458// !!!!! !!!!!1459// Check that a "label" operand occurs last in the operand list, if present1460return true;1461}14621463void InstructForm::dump() {1464output(stderr);1465}14661467void InstructForm::output(FILE *fp) {1468fprintf(fp,"\nInstruction: %s\n", (_ident?_ident:""));1469if (_matrule) _matrule->output(fp);1470if (_insencode) _insencode->output(fp);1471if (_constant) _constant->output(fp);1472if (_opcode) _opcode->output(fp);1473if (_attribs) _attribs->output(fp);1474if (_predicate) _predicate->output(fp);1475if (_effects.Size()) {1476fprintf(fp,"Effects\n");1477_effects.dump();1478}1479if (_exprule) _exprule->output(fp);1480if (_rewrule) _rewrule->output(fp);1481if (_format) _format->output(fp);1482if (_peephole) _peephole->output(fp);1483}14841485void MachNodeForm::dump() {1486output(stderr);1487}14881489void MachNodeForm::output(FILE *fp) {1490fprintf(fp,"\nMachNode: %s\n", (_ident?_ident:""));1491}14921493//------------------------------build_predicate--------------------------------1494// Build instruction predicates. If the user uses the same operand name1495// twice, we need to check that the operands are pointer-eequivalent in1496// the DFA during the labeling process.1497Predicate *InstructForm::build_predicate() {1498char buf[1024], *s=buf;1499Dict names(cmpstr,hashstr,Form::arena); // Map Names to counts15001501MatchNode *mnode =1502strcmp(_matrule->_opType, "Set") ? _matrule : _matrule->_rChild;1503mnode->count_instr_names(names);15041505uint first = 1;1506// Start with the predicate supplied in the .ad file.1507if( _predicate ) {1508if( first ) first=0;1509strcpy(s,"("); s += strlen(s);1510strcpy(s,_predicate->_pred);1511s += strlen(s);1512strcpy(s,")"); s += strlen(s);1513}1514for( DictI i(&names); i.test(); ++i ) {1515uintptr_t cnt = (uintptr_t)i._value;1516if( cnt > 1 ) { // Need a predicate at all?1517assert( cnt == 2, "Unimplemented" );1518// Handle many pairs1519if( first ) first=0;1520else { // All tests must pass, so use '&&'1521strcpy(s," && ");1522s += strlen(s);1523}1524// Add predicate to working buffer1525sprintf(s,"/*%s*/(",(char*)i._key);1526s += strlen(s);1527mnode->build_instr_pred(s,(char*)i._key,0);1528s += strlen(s);1529strcpy(s," == "); s += strlen(s);1530mnode->build_instr_pred(s,(char*)i._key,1);1531s += strlen(s);1532strcpy(s,")"); s += strlen(s);1533}1534}1535if( s == buf ) s = NULL;1536else {1537assert( strlen(buf) < sizeof(buf), "String buffer overflow" );1538s = strdup(buf);1539}1540return new Predicate(s);1541}15421543//------------------------------EncodeForm-------------------------------------1544// Constructor1545EncodeForm::EncodeForm()1546: _encClass(cmpstr,hashstr, Form::arena) {1547}1548EncodeForm::~EncodeForm() {1549}15501551// record a new register class1552EncClass *EncodeForm::add_EncClass(const char *className) {1553EncClass *encClass = new EncClass(className);1554_eclasses.addName(className);1555_encClass.Insert(className,encClass);1556return encClass;1557}15581559// Lookup the function body for an encoding class1560EncClass *EncodeForm::encClass(const char *className) {1561assert( className != NULL, "Must provide a defined encoding name");15621563EncClass *encClass = (EncClass*)_encClass[className];1564return encClass;1565}15661567// Lookup the function body for an encoding class1568const char *EncodeForm::encClassBody(const char *className) {1569if( className == NULL ) return NULL;15701571EncClass *encClass = (EncClass*)_encClass[className];1572assert( encClass != NULL, "Encode Class is missing.");1573encClass->_code.reset();1574const char *code = (const char*)encClass->_code.iter();1575assert( code != NULL, "Found an empty encode class body.");15761577return code;1578}15791580// Lookup the function body for an encoding class1581const char *EncodeForm::encClassPrototype(const char *className) {1582assert( className != NULL, "Encode class name must be non NULL.");15831584return className;1585}15861587void EncodeForm::dump() { // Debug printer1588output(stderr);1589}15901591void EncodeForm::output(FILE *fp) { // Write info to output files1592const char *name;1593fprintf(fp,"\n");1594fprintf(fp,"-------------------- Dump EncodeForm --------------------\n");1595for (_eclasses.reset(); (name = _eclasses.iter()) != NULL;) {1596((EncClass*)_encClass[name])->output(fp);1597}1598fprintf(fp,"-------------------- end EncodeForm --------------------\n");1599}1600//------------------------------EncClass---------------------------------------1601EncClass::EncClass(const char *name)1602: _localNames(cmpstr,hashstr, Form::arena), _name(name) {1603}1604EncClass::~EncClass() {1605}16061607// Add a parameter <type,name> pair1608void EncClass::add_parameter(const char *parameter_type, const char *parameter_name) {1609_parameter_type.addName( parameter_type );1610_parameter_name.addName( parameter_name );1611}16121613// Verify operand types in parameter list1614bool EncClass::check_parameter_types(FormDict &globals) {1615// !!!!!1616return false;1617}16181619// Add the decomposed "code" sections of an encoding's code-block1620void EncClass::add_code(const char *code) {1621_code.addName(code);1622}16231624// Add the decomposed "replacement variables" of an encoding's code-block1625void EncClass::add_rep_var(char *replacement_var) {1626_code.addName(NameList::_signal);1627_rep_vars.addName(replacement_var);1628}16291630// Lookup the function body for an encoding class1631int EncClass::rep_var_index(const char *rep_var) {1632uint position = 0;1633const char *name = NULL;16341635_parameter_name.reset();1636while ( (name = _parameter_name.iter()) != NULL ) {1637if ( strcmp(rep_var,name) == 0 ) return position;1638++position;1639}16401641return -1;1642}16431644// Check after parsing1645bool EncClass::verify() {1646// 1!!!!1647// Check that each replacement variable, '$name' in architecture description1648// is actually a local variable for this encode class, or a reserved name1649// "primary, secondary, tertiary"1650return true;1651}16521653void EncClass::dump() {1654output(stderr);1655}16561657// Write info to output files1658void EncClass::output(FILE *fp) {1659fprintf(fp,"EncClass: %s", (_name ? _name : ""));16601661// Output the parameter list1662_parameter_type.reset();1663_parameter_name.reset();1664const char *type = _parameter_type.iter();1665const char *name = _parameter_name.iter();1666fprintf(fp, " ( ");1667for ( ; (type != NULL) && (name != NULL);1668(type = _parameter_type.iter()), (name = _parameter_name.iter()) ) {1669fprintf(fp, " %s %s,", type, name);1670}1671fprintf(fp, " ) ");16721673// Output the code block1674_code.reset();1675_rep_vars.reset();1676const char *code;1677while ( (code = _code.iter()) != NULL ) {1678if ( _code.is_signal(code) ) {1679// A replacement variable1680const char *rep_var = _rep_vars.iter();1681fprintf(fp,"($%s)", rep_var);1682} else {1683// A section of code1684fprintf(fp,"%s", code);1685}1686}16871688}16891690//------------------------------Opcode-----------------------------------------1691Opcode::Opcode(char *primary, char *secondary, char *tertiary)1692: _primary(primary), _secondary(secondary), _tertiary(tertiary) {1693}16941695Opcode::~Opcode() {1696}16971698Opcode::opcode_type Opcode::as_opcode_type(const char *param) {1699if( strcmp(param,"primary") == 0 ) {1700return Opcode::PRIMARY;1701}1702else if( strcmp(param,"secondary") == 0 ) {1703return Opcode::SECONDARY;1704}1705else if( strcmp(param,"tertiary") == 0 ) {1706return Opcode::TERTIARY;1707}1708return Opcode::NOT_AN_OPCODE;1709}17101711bool Opcode::print_opcode(FILE *fp, Opcode::opcode_type desired_opcode) {1712// Default values previously provided by MachNode::primary()...1713const char *description = NULL;1714const char *value = NULL;1715// Check if user provided any opcode definitions1716if( this != NULL ) {1717// Update 'value' if user provided a definition in the instruction1718switch (desired_opcode) {1719case PRIMARY:1720description = "primary()";1721if( _primary != NULL) { value = _primary; }1722break;1723case SECONDARY:1724description = "secondary()";1725if( _secondary != NULL ) { value = _secondary; }1726break;1727case TERTIARY:1728description = "tertiary()";1729if( _tertiary != NULL ) { value = _tertiary; }1730break;1731default:1732assert( false, "ShouldNotReachHere();");1733break;1734}1735}1736if (value != NULL) {1737fprintf(fp, "(%s /*%s*/)", value, description);1738}1739return value != NULL;1740}17411742void Opcode::dump() {1743output(stderr);1744}17451746// Write info to output files1747void Opcode::output(FILE *fp) {1748if (_primary != NULL) fprintf(fp,"Primary opcode: %s\n", _primary);1749if (_secondary != NULL) fprintf(fp,"Secondary opcode: %s\n", _secondary);1750if (_tertiary != NULL) fprintf(fp,"Tertiary opcode: %s\n", _tertiary);1751}17521753//------------------------------InsEncode--------------------------------------1754InsEncode::InsEncode() {1755}1756InsEncode::~InsEncode() {1757}17581759// Add "encode class name" and its parameters1760NameAndList *InsEncode::add_encode(char *encoding) {1761assert( encoding != NULL, "Must provide name for encoding");17621763// add_parameter(NameList::_signal);1764NameAndList *encode = new NameAndList(encoding);1765_encoding.addName((char*)encode);17661767return encode;1768}17691770// Access the list of encodings1771void InsEncode::reset() {1772_encoding.reset();1773// _parameter.reset();1774}1775const char* InsEncode::encode_class_iter() {1776NameAndList *encode_class = (NameAndList*)_encoding.iter();1777return ( encode_class != NULL ? encode_class->name() : NULL );1778}1779// Obtain parameter name from zero based index1780const char *InsEncode::rep_var_name(InstructForm &inst, uint param_no) {1781NameAndList *params = (NameAndList*)_encoding.current();1782assert( params != NULL, "Internal Error");1783const char *param = (*params)[param_no];17841785// Remove '$' if parser placed it there.1786return ( param != NULL && *param == '$') ? (param+1) : param;1787}17881789void InsEncode::dump() {1790output(stderr);1791}17921793// Write info to output files1794void InsEncode::output(FILE *fp) {1795NameAndList *encoding = NULL;1796const char *parameter = NULL;17971798fprintf(fp,"InsEncode: ");1799_encoding.reset();18001801while ( (encoding = (NameAndList*)_encoding.iter()) != 0 ) {1802// Output the encoding being used1803fprintf(fp,"%s(", encoding->name() );18041805// Output its parameter list, if any1806bool first_param = true;1807encoding->reset();1808while ( (parameter = encoding->iter()) != 0 ) {1809// Output the ',' between parameters1810if ( ! first_param ) fprintf(fp,", ");1811first_param = false;1812// Output the parameter1813fprintf(fp,"%s", parameter);1814} // done with parameters1815fprintf(fp,") ");1816} // done with encodings18171818fprintf(fp,"\n");1819}18201821//------------------------------Effect-----------------------------------------1822static int effect_lookup(const char *name) {1823if(!strcmp(name, "USE")) return Component::USE;1824if(!strcmp(name, "DEF")) return Component::DEF;1825if(!strcmp(name, "USE_DEF")) return Component::USE_DEF;1826if(!strcmp(name, "KILL")) return Component::KILL;1827if(!strcmp(name, "USE_KILL")) return Component::USE_KILL;1828if(!strcmp(name, "TEMP")) return Component::TEMP;1829if(!strcmp(name, "INVALID")) return Component::INVALID;1830if(!strcmp(name, "CALL")) return Component::CALL;1831assert( false,"Invalid effect name specified\n");1832return Component::INVALID;1833}18341835const char *Component::getUsedefName() {1836switch (_usedef) {1837case Component::INVALID: return "INVALID"; break;1838case Component::USE: return "USE"; break;1839case Component::USE_DEF: return "USE_DEF"; break;1840case Component::USE_KILL: return "USE_KILL"; break;1841case Component::KILL: return "KILL"; break;1842case Component::TEMP: return "TEMP"; break;1843case Component::DEF: return "DEF"; break;1844case Component::CALL: return "CALL"; break;1845default: assert(false, "unknown effect");1846}1847return "Undefined Use/Def info";1848}18491850Effect::Effect(const char *name) : _name(name), _use_def(effect_lookup(name)) {1851_ftype = Form::EFF;1852}18531854Effect::~Effect() {1855}18561857// Dynamic type check1858Effect *Effect::is_effect() const {1859return (Effect*)this;1860}186118621863// True if this component is equal to the parameter.1864bool Effect::is(int use_def_kill_enum) const {1865return (_use_def == use_def_kill_enum ? true : false);1866}1867// True if this component is used/def'd/kill'd as the parameter suggests.1868bool Effect::isa(int use_def_kill_enum) const {1869return (_use_def & use_def_kill_enum) == use_def_kill_enum;1870}18711872void Effect::dump() {1873output(stderr);1874}18751876void Effect::output(FILE *fp) { // Write info to output files1877fprintf(fp,"Effect: %s\n", (_name?_name:""));1878}18791880//------------------------------ExpandRule-------------------------------------1881ExpandRule::ExpandRule() : _expand_instrs(),1882_newopconst(cmpstr, hashstr, Form::arena) {1883_ftype = Form::EXP;1884}18851886ExpandRule::~ExpandRule() { // Destructor1887}18881889void ExpandRule::add_instruction(NameAndList *instruction_name_and_operand_list) {1890_expand_instrs.addName((char*)instruction_name_and_operand_list);1891}18921893void ExpandRule::reset_instructions() {1894_expand_instrs.reset();1895}18961897NameAndList* ExpandRule::iter_instructions() {1898return (NameAndList*)_expand_instrs.iter();1899}190019011902void ExpandRule::dump() {1903output(stderr);1904}19051906void ExpandRule::output(FILE *fp) { // Write info to output files1907NameAndList *expand_instr = NULL;1908const char *opid = NULL;19091910fprintf(fp,"\nExpand Rule:\n");19111912// Iterate over the instructions 'node' expands into1913for(reset_instructions(); (expand_instr = iter_instructions()) != NULL; ) {1914fprintf(fp,"%s(", expand_instr->name());19151916// iterate over the operand list1917for( expand_instr->reset(); (opid = expand_instr->iter()) != NULL; ) {1918fprintf(fp,"%s ", opid);1919}1920fprintf(fp,");\n");1921}1922}19231924//------------------------------RewriteRule------------------------------------1925RewriteRule::RewriteRule(char* params, char* block)1926: _tempParams(params), _tempBlock(block) { }; // Constructor1927RewriteRule::~RewriteRule() { // Destructor1928}19291930void RewriteRule::dump() {1931output(stderr);1932}19331934void RewriteRule::output(FILE *fp) { // Write info to output files1935fprintf(fp,"\nRewrite Rule:\n%s\n%s\n",1936(_tempParams?_tempParams:""),1937(_tempBlock?_tempBlock:""));1938}193919401941//==============================MachNodes======================================1942//------------------------------MachNodeForm-----------------------------------1943MachNodeForm::MachNodeForm(char *id)1944: _ident(id) {1945}19461947MachNodeForm::~MachNodeForm() {1948}19491950MachNodeForm *MachNodeForm::is_machnode() const {1951return (MachNodeForm*)this;1952}19531954//==============================Operand Classes================================1955//------------------------------OpClassForm------------------------------------1956OpClassForm::OpClassForm(const char* id) : _ident(id) {1957_ftype = Form::OPCLASS;1958}19591960OpClassForm::~OpClassForm() {1961}19621963bool OpClassForm::ideal_only() const { return 0; }19641965OpClassForm *OpClassForm::is_opclass() const {1966return (OpClassForm*)this;1967}19681969Form::InterfaceType OpClassForm::interface_type(FormDict &globals) const {1970if( _oplst.count() == 0 ) return Form::no_interface;19711972// Check that my operands have the same interface type1973Form::InterfaceType interface;1974bool first = true;1975NameList &op_list = (NameList &)_oplst;1976op_list.reset();1977const char *op_name;1978while( (op_name = op_list.iter()) != NULL ) {1979const Form *form = globals[op_name];1980OperandForm *operand = form->is_operand();1981assert( operand, "Entry in operand class that is not an operand");1982if( first ) {1983first = false;1984interface = operand->interface_type(globals);1985} else {1986interface = (interface == operand->interface_type(globals) ? interface : Form::no_interface);1987}1988}1989return interface;1990}19911992bool OpClassForm::stack_slots_only(FormDict &globals) const {1993if( _oplst.count() == 0 ) return false; // how?19941995NameList &op_list = (NameList &)_oplst;1996op_list.reset();1997const char *op_name;1998while( (op_name = op_list.iter()) != NULL ) {1999const Form *form = globals[op_name];2000OperandForm *operand = form->is_operand();2001assert( operand, "Entry in operand class that is not an operand");2002if( !operand->stack_slots_only(globals) ) return false;2003}2004return true;2005}200620072008void OpClassForm::dump() {2009output(stderr);2010}20112012void OpClassForm::output(FILE *fp) {2013const char *name;2014fprintf(fp,"\nOperand Class: %s\n", (_ident?_ident:""));2015fprintf(fp,"\nCount = %d\n", _oplst.count());2016for(_oplst.reset(); (name = _oplst.iter()) != NULL;) {2017fprintf(fp,"%s, ",name);2018}2019fprintf(fp,"\n");2020}202120222023//==============================Operands=======================================2024//------------------------------OperandForm------------------------------------2025OperandForm::OperandForm(const char* id)2026: OpClassForm(id), _ideal_only(false),2027_localNames(cmpstr, hashstr, Form::arena) {2028_ftype = Form::OPER;20292030_matrule = NULL;2031_interface = NULL;2032_attribs = NULL;2033_predicate = NULL;2034_constraint= NULL;2035_construct = NULL;2036_format = NULL;2037}2038OperandForm::OperandForm(const char* id, bool ideal_only)2039: OpClassForm(id), _ideal_only(ideal_only),2040_localNames(cmpstr, hashstr, Form::arena) {2041_ftype = Form::OPER;20422043_matrule = NULL;2044_interface = NULL;2045_attribs = NULL;2046_predicate = NULL;2047_constraint= NULL;2048_construct = NULL;2049_format = NULL;2050}2051OperandForm::~OperandForm() {2052}205320542055OperandForm *OperandForm::is_operand() const {2056return (OperandForm*)this;2057}20582059bool OperandForm::ideal_only() const {2060return _ideal_only;2061}20622063Form::InterfaceType OperandForm::interface_type(FormDict &globals) const {2064if( _interface == NULL ) return Form::no_interface;20652066return _interface->interface_type(globals);2067}206820692070bool OperandForm::stack_slots_only(FormDict &globals) const {2071if( _constraint == NULL ) return false;2072return _constraint->stack_slots_only();2073}207420752076// Access op_cost attribute or return NULL.2077const char* OperandForm::cost() {2078for (Attribute* cur = _attribs; cur != NULL; cur = (Attribute*)cur->_next) {2079if( strcmp(cur->_ident,AttributeForm::_op_cost) == 0 ) {2080return cur->_val;2081}2082}2083return NULL;2084}20852086// Return the number of leaves below this complex operand2087uint OperandForm::num_leaves() const {2088if ( ! _matrule) return 0;20892090int num_leaves = _matrule->_numleaves;2091return num_leaves;2092}20932094// Return the number of constants contained within this complex operand2095uint OperandForm::num_consts(FormDict &globals) const {2096if ( ! _matrule) return 0;20972098// This is a recursive invocation on all operands in the matchrule2099return _matrule->num_consts(globals);2100}21012102// Return the number of constants in match rule with specified type2103uint OperandForm::num_consts(FormDict &globals, Form::DataType type) const {2104if ( ! _matrule) return 0;21052106// This is a recursive invocation on all operands in the matchrule2107return _matrule->num_consts(globals, type);2108}21092110// Return the number of pointer constants contained within this complex operand2111uint OperandForm::num_const_ptrs(FormDict &globals) const {2112if ( ! _matrule) return 0;21132114// This is a recursive invocation on all operands in the matchrule2115return _matrule->num_const_ptrs(globals);2116}21172118uint OperandForm::num_edges(FormDict &globals) const {2119uint edges = 0;2120uint leaves = num_leaves();2121uint consts = num_consts(globals);21222123// If we are matching a constant directly, there are no leaves.2124edges = ( leaves > consts ) ? leaves - consts : 0;21252126// !!!!!2127// Special case operands that do not have a corresponding ideal node.2128if( (edges == 0) && (consts == 0) ) {2129if( constrained_reg_class() != NULL ) {2130edges = 1;2131} else {2132if( _matrule2133&& (_matrule->_lChild == NULL) && (_matrule->_rChild == NULL) ) {2134const Form *form = globals[_matrule->_opType];2135OperandForm *oper = form ? form->is_operand() : NULL;2136if( oper ) {2137return oper->num_edges(globals);2138}2139}2140}2141}21422143return edges;2144}214521462147// Check if this operand is usable for cisc-spilling2148bool OperandForm::is_cisc_reg(FormDict &globals) const {2149const char *ideal = ideal_type(globals);2150bool is_cisc_reg = (ideal && (ideal_to_Reg_type(ideal) != none));2151return is_cisc_reg;2152}21532154bool OpClassForm::is_cisc_mem(FormDict &globals) const {2155Form::InterfaceType my_interface = interface_type(globals);2156return (my_interface == memory_interface);2157}215821592160// node matches ideal 'Bool'2161bool OperandForm::is_ideal_bool() const {2162if( _matrule == NULL ) return false;21632164return _matrule->is_ideal_bool();2165}21662167// Require user's name for an sRegX to be stackSlotX2168Form::DataType OperandForm::is_user_name_for_sReg() const {2169DataType data_type = none;2170if( _ident != NULL ) {2171if( strcmp(_ident,"stackSlotI") == 0 ) data_type = Form::idealI;2172else if( strcmp(_ident,"stackSlotP") == 0 ) data_type = Form::idealP;2173else if( strcmp(_ident,"stackSlotD") == 0 ) data_type = Form::idealD;2174else if( strcmp(_ident,"stackSlotF") == 0 ) data_type = Form::idealF;2175else if( strcmp(_ident,"stackSlotL") == 0 ) data_type = Form::idealL;2176}2177assert((data_type == none) || (_matrule == NULL), "No match-rule for stackSlotX");21782179return data_type;2180}218121822183// Return ideal type, if there is a single ideal type for this operand2184const char *OperandForm::ideal_type(FormDict &globals, RegisterForm *registers) const {2185const char *type = NULL;2186if (ideal_only()) type = _ident;2187else if( _matrule == NULL ) {2188// Check for condition code register2189const char *rc_name = constrained_reg_class();2190// !!!!!2191if (rc_name == NULL) return NULL;2192// !!!!! !!!!!2193// Check constraints on result's register class2194if( registers ) {2195RegClass *reg_class = registers->getRegClass(rc_name);2196assert( reg_class != NULL, "Register class is not defined");21972198// Check for ideal type of entries in register class, all are the same type2199reg_class->reset();2200RegDef *reg_def = reg_class->RegDef_iter();2201assert( reg_def != NULL, "No entries in register class");2202assert( reg_def->_idealtype != NULL, "Did not define ideal type for register");2203// Return substring that names the register's ideal type2204type = reg_def->_idealtype + 3;2205assert( *(reg_def->_idealtype + 0) == 'O', "Expect Op_ prefix");2206assert( *(reg_def->_idealtype + 1) == 'p', "Expect Op_ prefix");2207assert( *(reg_def->_idealtype + 2) == '_', "Expect Op_ prefix");2208}2209}2210else if( _matrule->_lChild == NULL && _matrule->_rChild == NULL ) {2211// This operand matches a single type, at the top level.2212// Check for ideal type2213type = _matrule->_opType;2214if( strcmp(type,"Bool") == 0 )2215return "Bool";2216// transitive lookup2217const Form *frm = globals[type];2218OperandForm *op = frm->is_operand();2219type = op->ideal_type(globals, registers);2220}2221return type;2222}222322242225// If there is a single ideal type for this interface field, return it.2226const char *OperandForm::interface_ideal_type(FormDict &globals,2227const char *field) const {2228const char *ideal_type = NULL;2229const char *value = NULL;22302231// Check if "field" is valid for this operand's interface2232if ( ! is_interface_field(field, value) ) return ideal_type;22332234// !!!!! !!!!! !!!!!2235// If a valid field has a constant value, identify "ConI" or "ConP" or ...22362237// Else, lookup type of field's replacement variable22382239return ideal_type;2240}224122422243RegClass* OperandForm::get_RegClass() const {2244if (_interface && !_interface->is_RegInterface()) return NULL;2245return globalAD->get_registers()->getRegClass(constrained_reg_class());2246}224722482249bool OperandForm::is_bound_register() const {2250RegClass* reg_class = get_RegClass();2251if (reg_class == NULL) {2252return false;2253}22542255const char* name = ideal_type(globalAD->globalNames());2256if (name == NULL) {2257return false;2258}22592260uint size = 0;2261if (strcmp(name, "RegFlags") == 0) size = 1;2262if (strcmp(name, "RegI") == 0) size = 1;2263if (strcmp(name, "RegF") == 0) size = 1;2264if (strcmp(name, "RegD") == 0) size = 2;2265if (strcmp(name, "RegL") == 0) size = 2;2266if (strcmp(name, "RegN") == 0) size = 1;2267if (strcmp(name, "RegP") == 0) size = globalAD->get_preproc_def("_LP64") ? 2 : 1;2268if (size == 0) {2269return false;2270}2271return size == reg_class->size();2272}227322742275// Check if this is a valid field for this operand,2276// Return 'true' if valid, and set the value to the string the user provided.2277bool OperandForm::is_interface_field(const char *field,2278const char * &value) const {2279return false;2280}228122822283// Return register class name if a constraint specifies the register class.2284const char *OperandForm::constrained_reg_class() const {2285const char *reg_class = NULL;2286if ( _constraint ) {2287// !!!!!2288Constraint *constraint = _constraint;2289if ( strcmp(_constraint->_func,"ALLOC_IN_RC") == 0 ) {2290reg_class = _constraint->_arg;2291}2292}22932294return reg_class;2295}229622972298// Return the register class associated with 'leaf'.2299const char *OperandForm::in_reg_class(uint leaf, FormDict &globals) {2300const char *reg_class = NULL; // "RegMask::Empty";23012302if((_matrule == NULL) || (_matrule->is_chain_rule(globals))) {2303reg_class = constrained_reg_class();2304return reg_class;2305}2306const char *result = NULL;2307const char *name = NULL;2308const char *type = NULL;2309// iterate through all base operands2310// until we reach the register that corresponds to "leaf"2311// This function is not looking for an ideal type. It needs the first2312// level user type associated with the leaf.2313for(uint idx = 0;_matrule->base_operand(idx,globals,result,name,type);++idx) {2314const Form *form = (_localNames[name] ? _localNames[name] : globals[result]);2315OperandForm *oper = form ? form->is_operand() : NULL;2316if( oper ) {2317reg_class = oper->constrained_reg_class();2318if( reg_class ) {2319reg_class = reg_class;2320} else {2321// ShouldNotReachHere();2322}2323} else {2324// ShouldNotReachHere();2325}23262327// Increment our target leaf position if current leaf is not a candidate.2328if( reg_class == NULL) ++leaf;2329// Exit the loop with the value of reg_class when at the correct index2330if( idx == leaf ) break;2331// May iterate through all base operands if reg_class for 'leaf' is NULL2332}2333return reg_class;2334}233523362337// Recursive call to construct list of top-level operands.2338// Implementation does not modify state of internal structures2339void OperandForm::build_components() {2340if (_matrule) _matrule->append_components(_localNames, _components);23412342// Add parameters that "do not appear in match rule".2343const char *name;2344for (_parameters.reset(); (name = _parameters.iter()) != NULL;) {2345OpClassForm *opForm = _localNames[name]->is_opclass();2346assert(opForm != NULL, "sanity");23472348if ( _components.operand_position(name) == -1 ) {2349_components.insert(name, opForm->_ident, Component::INVALID, false);2350}2351}23522353return;2354}23552356int OperandForm::operand_position(const char *name, int usedef) {2357return _components.operand_position(name, usedef, this);2358}235923602361// Return zero-based position in component list, only counting constants;2362// Return -1 if not in list.2363int OperandForm::constant_position(FormDict &globals, const Component *last) {2364// Iterate through components and count constants preceding 'constant'2365int position = 0;2366Component *comp;2367_components.reset();2368while( (comp = _components.iter()) != NULL && (comp != last) ) {2369// Special case for operands that take a single user-defined operand2370// Skip the initial definition in the component list.2371if( strcmp(comp->_name,this->_ident) == 0 ) continue;23722373const char *type = comp->_type;2374// Lookup operand form for replacement variable's type2375const Form *form = globals[type];2376assert( form != NULL, "Component's type not found");2377OperandForm *oper = form ? form->is_operand() : NULL;2378if( oper ) {2379if( oper->_matrule->is_base_constant(globals) != Form::none ) {2380++position;2381}2382}2383}23842385// Check for being passed a component that was not in the list2386if( comp != last ) position = -1;23872388return position;2389}2390// Provide position of constant by "name"2391int OperandForm::constant_position(FormDict &globals, const char *name) {2392const Component *comp = _components.search(name);2393int idx = constant_position( globals, comp );23942395return idx;2396}239723982399// Return zero-based position in component list, only counting constants;2400// Return -1 if not in list.2401int OperandForm::register_position(FormDict &globals, const char *reg_name) {2402// Iterate through components and count registers preceding 'last'2403uint position = 0;2404Component *comp;2405_components.reset();2406while( (comp = _components.iter()) != NULL2407&& (strcmp(comp->_name,reg_name) != 0) ) {2408// Special case for operands that take a single user-defined operand2409// Skip the initial definition in the component list.2410if( strcmp(comp->_name,this->_ident) == 0 ) continue;24112412const char *type = comp->_type;2413// Lookup operand form for component's type2414const Form *form = globals[type];2415assert( form != NULL, "Component's type not found");2416OperandForm *oper = form ? form->is_operand() : NULL;2417if( oper ) {2418if( oper->_matrule->is_base_register(globals) ) {2419++position;2420}2421}2422}24232424return position;2425}242624272428const char *OperandForm::reduce_result() const {2429return _ident;2430}2431// Return the name of the operand on the right hand side of the binary match2432// Return NULL if there is no right hand side2433const char *OperandForm::reduce_right(FormDict &globals) const {2434return ( _matrule ? _matrule->reduce_right(globals) : NULL );2435}24362437// Similar for left2438const char *OperandForm::reduce_left(FormDict &globals) const {2439return ( _matrule ? _matrule->reduce_left(globals) : NULL );2440}244124422443// --------------------------- FILE *output_routines2444//2445// Output code for disp_is_oop, if true.2446void OperandForm::disp_is_oop(FILE *fp, FormDict &globals) {2447// Check it is a memory interface with a non-user-constant disp field2448if ( this->_interface == NULL ) return;2449MemInterface *mem_interface = this->_interface->is_MemInterface();2450if ( mem_interface == NULL ) return;2451const char *disp = mem_interface->_disp;2452if ( *disp != '$' ) return;24532454// Lookup replacement variable in operand's component list2455const char *rep_var = disp + 1;2456const Component *comp = this->_components.search(rep_var);2457assert( comp != NULL, "Replacement variable not found in components");2458// Lookup operand form for replacement variable's type2459const char *type = comp->_type;2460Form *form = (Form*)globals[type];2461assert( form != NULL, "Replacement variable's type not found");2462OperandForm *op = form->is_operand();2463assert( op, "Memory Interface 'disp' can only emit an operand form");2464// Check if this is a ConP, which may require relocation2465if ( op->is_base_constant(globals) == Form::idealP ) {2466// Find the constant's index: _c0, _c1, _c2, ... , _cN2467uint idx = op->constant_position( globals, rep_var);2468fprintf(fp," virtual relocInfo::relocType disp_reloc() const {");2469fprintf(fp, " return _c%d->reloc();", idx);2470fprintf(fp, " }\n");2471}2472}24732474// Generate code for internal and external format methods2475//2476// internal access to reg# node->_idx2477// access to subsumed constant _c0, _c1,2478void OperandForm::int_format(FILE *fp, FormDict &globals, uint index) {2479Form::DataType dtype;2480if (_matrule && (_matrule->is_base_register(globals) ||2481strcmp(ideal_type(globalAD->globalNames()), "RegFlags") == 0)) {2482// !!!!! !!!!!2483fprintf(fp," { char reg_str[128];\n");2484fprintf(fp," ra->dump_register(node,reg_str);\n");2485fprintf(fp," st->print(\"%cs\",reg_str);\n",'%');2486fprintf(fp," }\n");2487} else if (_matrule && (dtype = _matrule->is_base_constant(globals)) != Form::none) {2488format_constant( fp, index, dtype );2489} else if (ideal_to_sReg_type(_ident) != Form::none) {2490// Special format for Stack Slot Register2491fprintf(fp," { char reg_str[128];\n");2492fprintf(fp," ra->dump_register(node,reg_str);\n");2493fprintf(fp," st->print(\"%cs\",reg_str);\n",'%');2494fprintf(fp," }\n");2495} else {2496fprintf(fp," st->print(\"No format defined for %s\n\");\n", _ident);2497fflush(fp);2498fprintf(stderr,"No format defined for %s\n", _ident);2499dump();2500assert( false,"Internal error:\n output_internal_operand() attempting to output other than a Register or Constant");2501}2502}25032504// Similar to "int_format" but for cases where data is external to operand2505// external access to reg# node->in(idx)->_idx,2506void OperandForm::ext_format(FILE *fp, FormDict &globals, uint index) {2507Form::DataType dtype;2508if (_matrule && (_matrule->is_base_register(globals) ||2509strcmp(ideal_type(globalAD->globalNames()), "RegFlags") == 0)) {2510fprintf(fp," { char reg_str[128];\n");2511fprintf(fp," ra->dump_register(node->in(idx");2512if ( index != 0 ) fprintf(fp, "+%d",index);2513fprintf(fp, "),reg_str);\n");2514fprintf(fp," st->print(\"%cs\",reg_str);\n",'%');2515fprintf(fp," }\n");2516} else if (_matrule && (dtype = _matrule->is_base_constant(globals)) != Form::none) {2517format_constant( fp, index, dtype );2518} else if (ideal_to_sReg_type(_ident) != Form::none) {2519// Special format for Stack Slot Register2520fprintf(fp," { char reg_str[128];\n");2521fprintf(fp," ra->dump_register(node->in(idx");2522if ( index != 0 ) fprintf(fp, "+%d",index);2523fprintf(fp, "),reg_str);\n");2524fprintf(fp," st->print(\"%cs\",reg_str);\n",'%');2525fprintf(fp," }\n");2526} else {2527fprintf(fp," st->print(\"No format defined for %s\n\");\n", _ident);2528assert( false,"Internal error:\n output_external_operand() attempting to output other than a Register or Constant");2529}2530}25312532void OperandForm::format_constant(FILE *fp, uint const_index, uint const_type) {2533switch(const_type) {2534case Form::idealI: fprintf(fp," st->print(\"#%%d\", _c%d);\n", const_index); break;2535case Form::idealP: fprintf(fp," if (_c%d) _c%d->dump_on(st);\n", const_index, const_index); break;2536case Form::idealNKlass:2537case Form::idealN: fprintf(fp," if (_c%d) _c%d->dump_on(st);\n", const_index, const_index); break;2538case Form::idealL: fprintf(fp," st->print(\"#\" INT64_FORMAT, (int64_t)_c%d);\n", const_index); break;2539case Form::idealF: fprintf(fp," st->print(\"#%%f\", _c%d);\n", const_index); break;2540case Form::idealD: fprintf(fp," st->print(\"#%%f\", _c%d);\n", const_index); break;2541default:2542assert( false, "ShouldNotReachHere()");2543}2544}25452546// Return the operand form corresponding to the given index, else NULL.2547OperandForm *OperandForm::constant_operand(FormDict &globals,2548uint index) {2549// !!!!!2550// Check behavior on complex operands2551uint n_consts = num_consts(globals);2552if( n_consts > 0 ) {2553uint i = 0;2554const char *type;2555Component *comp;2556_components.reset();2557if ((comp = _components.iter()) == NULL) {2558assert(n_consts == 1, "Bad component list detected.\n");2559// Current operand is THE operand2560if ( index == 0 ) {2561return this;2562}2563} // end if NULL2564else {2565// Skip the first component, it can not be a DEF of a constant2566do {2567type = comp->base_type(globals);2568// Check that "type" is a 'ConI', 'ConP', ...2569if ( ideal_to_const_type(type) != Form::none ) {2570// When at correct component, get corresponding Operand2571if ( index == 0 ) {2572return globals[comp->_type]->is_operand();2573}2574// Decrement number of constants to go2575--index;2576}2577} while((comp = _components.iter()) != NULL);2578}2579}25802581// Did not find a constant for this index.2582return NULL;2583}25842585// If this operand has a single ideal type, return its type2586Form::DataType OperandForm::simple_type(FormDict &globals) const {2587const char *type_name = ideal_type(globals);2588Form::DataType type = type_name ? ideal_to_const_type( type_name )2589: Form::none;2590return type;2591}25922593Form::DataType OperandForm::is_base_constant(FormDict &globals) const {2594if ( _matrule == NULL ) return Form::none;25952596return _matrule->is_base_constant(globals);2597}25982599// "true" if this operand is a simple type that is swallowed2600bool OperandForm::swallowed(FormDict &globals) const {2601Form::DataType type = simple_type(globals);2602if( type != Form::none ) {2603return true;2604}26052606return false;2607}26082609// Output code to access the value of the index'th constant2610void OperandForm::access_constant(FILE *fp, FormDict &globals,2611uint const_index) {2612OperandForm *oper = constant_operand(globals, const_index);2613assert( oper, "Index exceeds number of constants in operand");2614Form::DataType dtype = oper->is_base_constant(globals);26152616switch(dtype) {2617case idealI: fprintf(fp,"_c%d", const_index); break;2618case idealP: fprintf(fp,"_c%d->get_con()",const_index); break;2619case idealL: fprintf(fp,"_c%d", const_index); break;2620case idealF: fprintf(fp,"_c%d", const_index); break;2621case idealD: fprintf(fp,"_c%d", const_index); break;2622default:2623assert( false, "ShouldNotReachHere()");2624}2625}262626272628void OperandForm::dump() {2629output(stderr);2630}26312632void OperandForm::output(FILE *fp) {2633fprintf(fp,"\nOperand: %s\n", (_ident?_ident:""));2634if (_matrule) _matrule->dump();2635if (_interface) _interface->dump();2636if (_attribs) _attribs->dump();2637if (_predicate) _predicate->dump();2638if (_constraint) _constraint->dump();2639if (_construct) _construct->dump();2640if (_format) _format->dump();2641}26422643//------------------------------Constraint-------------------------------------2644Constraint::Constraint(const char *func, const char *arg)2645: _func(func), _arg(arg) {2646}2647Constraint::~Constraint() { /* not owner of char* */2648}26492650bool Constraint::stack_slots_only() const {2651return strcmp(_func, "ALLOC_IN_RC") == 02652&& strcmp(_arg, "stack_slots") == 0;2653}26542655void Constraint::dump() {2656output(stderr);2657}26582659void Constraint::output(FILE *fp) { // Write info to output files2660assert((_func != NULL && _arg != NULL),"missing constraint function or arg");2661fprintf(fp,"Constraint: %s ( %s )\n", _func, _arg);2662}26632664//------------------------------Predicate--------------------------------------2665Predicate::Predicate(char *pr)2666: _pred(pr) {2667}2668Predicate::~Predicate() {2669}26702671void Predicate::dump() {2672output(stderr);2673}26742675void Predicate::output(FILE *fp) {2676fprintf(fp,"Predicate"); // Write to output files2677}2678//------------------------------Interface--------------------------------------2679Interface::Interface(const char *name) : _name(name) {2680}2681Interface::~Interface() {2682}26832684Form::InterfaceType Interface::interface_type(FormDict &globals) const {2685Interface *thsi = (Interface*)this;2686if ( thsi->is_RegInterface() ) return Form::register_interface;2687if ( thsi->is_MemInterface() ) return Form::memory_interface;2688if ( thsi->is_ConstInterface() ) return Form::constant_interface;2689if ( thsi->is_CondInterface() ) return Form::conditional_interface;26902691return Form::no_interface;2692}26932694RegInterface *Interface::is_RegInterface() {2695if ( strcmp(_name,"REG_INTER") != 0 )2696return NULL;2697return (RegInterface*)this;2698}2699MemInterface *Interface::is_MemInterface() {2700if ( strcmp(_name,"MEMORY_INTER") != 0 ) return NULL;2701return (MemInterface*)this;2702}2703ConstInterface *Interface::is_ConstInterface() {2704if ( strcmp(_name,"CONST_INTER") != 0 ) return NULL;2705return (ConstInterface*)this;2706}2707CondInterface *Interface::is_CondInterface() {2708if ( strcmp(_name,"COND_INTER") != 0 ) return NULL;2709return (CondInterface*)this;2710}271127122713void Interface::dump() {2714output(stderr);2715}27162717// Write info to output files2718void Interface::output(FILE *fp) {2719fprintf(fp,"Interface: %s\n", (_name ? _name : "") );2720}27212722//------------------------------RegInterface-----------------------------------2723RegInterface::RegInterface() : Interface("REG_INTER") {2724}2725RegInterface::~RegInterface() {2726}27272728void RegInterface::dump() {2729output(stderr);2730}27312732// Write info to output files2733void RegInterface::output(FILE *fp) {2734Interface::output(fp);2735}27362737//------------------------------ConstInterface---------------------------------2738ConstInterface::ConstInterface() : Interface("CONST_INTER") {2739}2740ConstInterface::~ConstInterface() {2741}27422743void ConstInterface::dump() {2744output(stderr);2745}27462747// Write info to output files2748void ConstInterface::output(FILE *fp) {2749Interface::output(fp);2750}27512752//------------------------------MemInterface-----------------------------------2753MemInterface::MemInterface(char *base, char *index, char *scale, char *disp)2754: Interface("MEMORY_INTER"), _base(base), _index(index), _scale(scale), _disp(disp) {2755}2756MemInterface::~MemInterface() {2757// not owner of any character arrays2758}27592760void MemInterface::dump() {2761output(stderr);2762}27632764// Write info to output files2765void MemInterface::output(FILE *fp) {2766Interface::output(fp);2767if ( _base != NULL ) fprintf(fp," base == %s\n", _base);2768if ( _index != NULL ) fprintf(fp," index == %s\n", _index);2769if ( _scale != NULL ) fprintf(fp," scale == %s\n", _scale);2770if ( _disp != NULL ) fprintf(fp," disp == %s\n", _disp);2771// fprintf(fp,"\n");2772}27732774//------------------------------CondInterface----------------------------------2775CondInterface::CondInterface(const char* equal, const char* equal_format,2776const char* not_equal, const char* not_equal_format,2777const char* less, const char* less_format,2778const char* greater_equal, const char* greater_equal_format,2779const char* less_equal, const char* less_equal_format,2780const char* greater, const char* greater_format,2781const char* overflow, const char* overflow_format,2782const char* no_overflow, const char* no_overflow_format)2783: Interface("COND_INTER"),2784_equal(equal), _equal_format(equal_format),2785_not_equal(not_equal), _not_equal_format(not_equal_format),2786_less(less), _less_format(less_format),2787_greater_equal(greater_equal), _greater_equal_format(greater_equal_format),2788_less_equal(less_equal), _less_equal_format(less_equal_format),2789_greater(greater), _greater_format(greater_format),2790_overflow(overflow), _overflow_format(overflow_format),2791_no_overflow(no_overflow), _no_overflow_format(no_overflow_format) {2792}2793CondInterface::~CondInterface() {2794// not owner of any character arrays2795}27962797void CondInterface::dump() {2798output(stderr);2799}28002801// Write info to output files2802void CondInterface::output(FILE *fp) {2803Interface::output(fp);2804if ( _equal != NULL ) fprintf(fp," equal == %s\n", _equal);2805if ( _not_equal != NULL ) fprintf(fp," not_equal == %s\n", _not_equal);2806if ( _less != NULL ) fprintf(fp," less == %s\n", _less);2807if ( _greater_equal != NULL ) fprintf(fp," greater_equal == %s\n", _greater_equal);2808if ( _less_equal != NULL ) fprintf(fp," less_equal == %s\n", _less_equal);2809if ( _greater != NULL ) fprintf(fp," greater == %s\n", _greater);2810if ( _overflow != NULL ) fprintf(fp," overflow == %s\n", _overflow);2811if ( _no_overflow != NULL ) fprintf(fp," no_overflow == %s\n", _no_overflow);2812// fprintf(fp,"\n");2813}28142815//------------------------------ConstructRule----------------------------------2816ConstructRule::ConstructRule(char *cnstr)2817: _construct(cnstr) {2818}2819ConstructRule::~ConstructRule() {2820}28212822void ConstructRule::dump() {2823output(stderr);2824}28252826void ConstructRule::output(FILE *fp) {2827fprintf(fp,"\nConstruct Rule\n"); // Write to output files2828}282928302831//==============================Shared Forms===================================2832//------------------------------AttributeForm----------------------------------2833int AttributeForm::_insId = 0; // start counter at 02834int AttributeForm::_opId = 0; // start counter at 02835const char* AttributeForm::_ins_cost = "ins_cost"; // required name2836const char* AttributeForm::_op_cost = "op_cost"; // required name28372838AttributeForm::AttributeForm(char *attr, int type, char *attrdef)2839: Form(Form::ATTR), _attrname(attr), _atype(type), _attrdef(attrdef) {2840if (type==OP_ATTR) {2841id = ++_opId;2842}2843else if (type==INS_ATTR) {2844id = ++_insId;2845}2846else assert( false,"");2847}2848AttributeForm::~AttributeForm() {2849}28502851// Dynamic type check2852AttributeForm *AttributeForm::is_attribute() const {2853return (AttributeForm*)this;2854}285528562857// inlined // int AttributeForm::type() { return id;}28582859void AttributeForm::dump() {2860output(stderr);2861}28622863void AttributeForm::output(FILE *fp) {2864if( _attrname && _attrdef ) {2865fprintf(fp,"\n// AttributeForm \nstatic const int %s = %s;\n",2866_attrname, _attrdef);2867}2868else {2869fprintf(fp,"\n// AttributeForm missing name %s or definition %s\n",2870(_attrname?_attrname:""), (_attrdef?_attrdef:"") );2871}2872}28732874//------------------------------Component--------------------------------------2875Component::Component(const char *name, const char *type, int usedef)2876: _name(name), _type(type), _usedef(usedef) {2877_ftype = Form::COMP;2878}2879Component::~Component() {2880}28812882// True if this component is equal to the parameter.2883bool Component::is(int use_def_kill_enum) const {2884return (_usedef == use_def_kill_enum ? true : false);2885}2886// True if this component is used/def'd/kill'd as the parameter suggests.2887bool Component::isa(int use_def_kill_enum) const {2888return (_usedef & use_def_kill_enum) == use_def_kill_enum;2889}28902891// Extend this component with additional use/def/kill behavior2892int Component::promote_use_def_info(int new_use_def) {2893_usedef |= new_use_def;28942895return _usedef;2896}28972898// Check the base type of this component, if it has one2899const char *Component::base_type(FormDict &globals) {2900const Form *frm = globals[_type];2901if (frm == NULL) return NULL;2902OperandForm *op = frm->is_operand();2903if (op == NULL) return NULL;2904if (op->ideal_only()) return op->_ident;2905return (char *)op->ideal_type(globals);2906}29072908void Component::dump() {2909output(stderr);2910}29112912void Component::output(FILE *fp) {2913fprintf(fp,"Component:"); // Write to output files2914fprintf(fp, " name = %s", _name);2915fprintf(fp, ", type = %s", _type);2916assert(_usedef != 0, "unknown effect");2917fprintf(fp, ", use/def = %s\n", getUsedefName());2918}291929202921//------------------------------ComponentList---------------------------------2922ComponentList::ComponentList() : NameList(), _matchcnt(0) {2923}2924ComponentList::~ComponentList() {2925// // This list may not own its elements if copied via assignment2926// Component *component;2927// for (reset(); (component = iter()) != NULL;) {2928// delete component;2929// }2930}29312932void ComponentList::insert(Component *component, bool mflag) {2933NameList::addName((char *)component);2934if(mflag) _matchcnt++;2935}2936void ComponentList::insert(const char *name, const char *opType, int usedef,2937bool mflag) {2938Component * component = new Component(name, opType, usedef);2939insert(component, mflag);2940}2941Component *ComponentList::current() { return (Component*)NameList::current(); }2942Component *ComponentList::iter() { return (Component*)NameList::iter(); }2943Component *ComponentList::match_iter() {2944if(_iter < _matchcnt) return (Component*)NameList::iter();2945return NULL;2946}2947Component *ComponentList::post_match_iter() {2948Component *comp = iter();2949// At end of list?2950if ( comp == NULL ) {2951return comp;2952}2953// In post-match components?2954if (_iter > match_count()-1) {2955return comp;2956}29572958return post_match_iter();2959}29602961void ComponentList::reset() { NameList::reset(); }2962int ComponentList::count() { return NameList::count(); }29632964Component *ComponentList::operator[](int position) {2965// Shortcut complete iteration if there are not enough entries2966if (position >= count()) return NULL;29672968int index = 0;2969Component *component = NULL;2970for (reset(); (component = iter()) != NULL;) {2971if (index == position) {2972return component;2973}2974++index;2975}29762977return NULL;2978}29792980const Component *ComponentList::search(const char *name) {2981PreserveIter pi(this);2982reset();2983for( Component *comp = NULL; ((comp = iter()) != NULL); ) {2984if( strcmp(comp->_name,name) == 0 ) return comp;2985}29862987return NULL;2988}29892990// Return number of USEs + number of DEFs2991// When there are no components, or the first component is a USE,2992// then we add '1' to hold a space for the 'result' operand.2993int ComponentList::num_operands() {2994PreserveIter pi(this);2995uint count = 1; // result operand2996uint position = 0;29972998Component *component = NULL;2999for( reset(); (component = iter()) != NULL; ++position ) {3000if( component->isa(Component::USE) ||3001( position == 0 && (! component->isa(Component::DEF))) ) {3002++count;3003}3004}30053006return count;3007}30083009// Return zero-based position of operand 'name' in list; -1 if not in list.3010// if parameter 'usedef' is ::USE, it will match USE, USE_DEF, ...3011int ComponentList::operand_position(const char *name, int usedef, Form *fm) {3012PreserveIter pi(this);3013int position = 0;3014int num_opnds = num_operands();3015Component *component;3016Component* preceding_non_use = NULL;3017Component* first_def = NULL;3018for (reset(); (component = iter()) != NULL; ++position) {3019// When the first component is not a DEF,3020// leave space for the result operand!3021if ( position==0 && (! component->isa(Component::DEF)) ) {3022++position;3023++num_opnds;3024}3025if (strcmp(name, component->_name)==0 && (component->isa(usedef))) {3026// When the first entry in the component list is a DEF and a USE3027// Treat them as being separate, a DEF first, then a USE3028if( position==03029&& usedef==Component::USE && component->isa(Component::DEF) ) {3030assert(position+1 < num_opnds, "advertised index in bounds");3031return position+1;3032} else {3033if( preceding_non_use && strcmp(component->_name, preceding_non_use->_name) ) {3034fprintf(stderr, "the name '%s(%s)' should not precede the name '%s(%s)'",3035preceding_non_use->_name, preceding_non_use->getUsedefName(),3036name, component->getUsedefName());3037if (fm && fm->is_instruction()) fprintf(stderr, "in form '%s'", fm->is_instruction()->_ident);3038if (fm && fm->is_operand()) fprintf(stderr, "in form '%s'", fm->is_operand()->_ident);3039fprintf(stderr, "\n");3040}3041if( position >= num_opnds ) {3042fprintf(stderr, "the name '%s' is too late in its name list", name);3043if (fm && fm->is_instruction()) fprintf(stderr, "in form '%s'", fm->is_instruction()->_ident);3044if (fm && fm->is_operand()) fprintf(stderr, "in form '%s'", fm->is_operand()->_ident);3045fprintf(stderr, "\n");3046}3047assert(position < num_opnds, "advertised index in bounds");3048return position;3049}3050}3051if( component->isa(Component::DEF)3052&& component->isa(Component::USE) ) {3053++position;3054if( position != 1 ) --position; // only use two slots for the 1st USE_DEF3055}3056if( component->isa(Component::DEF) && !first_def ) {3057first_def = component;3058}3059if( !component->isa(Component::USE) && component != first_def ) {3060preceding_non_use = component;3061} else if( preceding_non_use && !strcmp(component->_name, preceding_non_use->_name) ) {3062preceding_non_use = NULL;3063}3064}3065return Not_in_list;3066}30673068// Find position for this name, regardless of use/def information3069int ComponentList::operand_position(const char *name) {3070PreserveIter pi(this);3071int position = 0;3072Component *component;3073for (reset(); (component = iter()) != NULL; ++position) {3074// When the first component is not a DEF,3075// leave space for the result operand!3076if ( position==0 && (! component->isa(Component::DEF)) ) {3077++position;3078}3079if (strcmp(name, component->_name)==0) {3080return position;3081}3082if( component->isa(Component::DEF)3083&& component->isa(Component::USE) ) {3084++position;3085if( position != 1 ) --position; // only use two slots for the 1st USE_DEF3086}3087}3088return Not_in_list;3089}30903091int ComponentList::operand_position_format(const char *name, Form *fm) {3092PreserveIter pi(this);3093int first_position = operand_position(name);3094int use_position = operand_position(name, Component::USE, fm);30953096return ((first_position < use_position) ? use_position : first_position);3097}30983099int ComponentList::label_position() {3100PreserveIter pi(this);3101int position = 0;3102reset();3103for( Component *comp; (comp = iter()) != NULL; ++position) {3104// When the first component is not a DEF,3105// leave space for the result operand!3106if ( position==0 && (! comp->isa(Component::DEF)) ) {3107++position;3108}3109if (strcmp(comp->_type, "label")==0) {3110return position;3111}3112if( comp->isa(Component::DEF)3113&& comp->isa(Component::USE) ) {3114++position;3115if( position != 1 ) --position; // only use two slots for the 1st USE_DEF3116}3117}31183119return -1;3120}31213122int ComponentList::method_position() {3123PreserveIter pi(this);3124int position = 0;3125reset();3126for( Component *comp; (comp = iter()) != NULL; ++position) {3127// When the first component is not a DEF,3128// leave space for the result operand!3129if ( position==0 && (! comp->isa(Component::DEF)) ) {3130++position;3131}3132if (strcmp(comp->_type, "method")==0) {3133return position;3134}3135if( comp->isa(Component::DEF)3136&& comp->isa(Component::USE) ) {3137++position;3138if( position != 1 ) --position; // only use two slots for the 1st USE_DEF3139}3140}31413142return -1;3143}31443145void ComponentList::dump() { output(stderr); }31463147void ComponentList::output(FILE *fp) {3148PreserveIter pi(this);3149fprintf(fp, "\n");3150Component *component;3151for (reset(); (component = iter()) != NULL;) {3152component->output(fp);3153}3154fprintf(fp, "\n");3155}31563157//------------------------------MatchNode--------------------------------------3158MatchNode::MatchNode(ArchDesc &ad, const char *result, const char *mexpr,3159const char *opType, MatchNode *lChild, MatchNode *rChild)3160: _AD(ad), _result(result), _name(mexpr), _opType(opType),3161_lChild(lChild), _rChild(rChild), _internalop(0), _numleaves(0),3162_commutative_id(0) {3163_numleaves = (lChild ? lChild->_numleaves : 0)3164+ (rChild ? rChild->_numleaves : 0);3165}31663167MatchNode::MatchNode(ArchDesc &ad, MatchNode& mnode)3168: _AD(ad), _result(mnode._result), _name(mnode._name),3169_opType(mnode._opType), _lChild(mnode._lChild), _rChild(mnode._rChild),3170_internalop(0), _numleaves(mnode._numleaves),3171_commutative_id(mnode._commutative_id) {3172}31733174MatchNode::MatchNode(ArchDesc &ad, MatchNode& mnode, int clone)3175: _AD(ad), _result(mnode._result), _name(mnode._name),3176_opType(mnode._opType),3177_internalop(0), _numleaves(mnode._numleaves),3178_commutative_id(mnode._commutative_id) {3179if (mnode._lChild) {3180_lChild = new MatchNode(ad, *mnode._lChild, clone);3181} else {3182_lChild = NULL;3183}3184if (mnode._rChild) {3185_rChild = new MatchNode(ad, *mnode._rChild, clone);3186} else {3187_rChild = NULL;3188}3189}31903191MatchNode::~MatchNode() {3192// // This node may not own its children if copied via assignment3193// if( _lChild ) delete _lChild;3194// if( _rChild ) delete _rChild;3195}31963197bool MatchNode::find_type(const char *type, int &position) const {3198if ( (_lChild != NULL) && (_lChild->find_type(type, position)) ) return true;3199if ( (_rChild != NULL) && (_rChild->find_type(type, position)) ) return true;32003201if (strcmp(type,_opType)==0) {3202return true;3203} else {3204++position;3205}3206return false;3207}32083209// Recursive call collecting info on top-level operands, not transitive.3210// Implementation does not modify state of internal structures.3211void MatchNode::append_components(FormDict& locals, ComponentList& components,3212bool def_flag) const {3213int usedef = def_flag ? Component::DEF : Component::USE;3214FormDict &globals = _AD.globalNames();32153216assert (_name != NULL, "MatchNode::build_components encountered empty node\n");3217// Base case3218if (_lChild==NULL && _rChild==NULL) {3219// If _opType is not an operation, do not build a component for it #####3220const Form *f = globals[_opType];3221if( f != NULL ) {3222// Add non-ideals that are operands, operand-classes,3223if( ! f->ideal_only()3224&& (f->is_opclass() || f->is_operand()) ) {3225components.insert(_name, _opType, usedef, true);3226}3227}3228return;3229}3230// Promote results of "Set" to DEF3231bool tmpdef_flag = (!strcmp(_opType, "Set")) ? true : false;3232if (_lChild) _lChild->append_components(locals, components, tmpdef_flag);3233tmpdef_flag = false; // only applies to component immediately following 'Set'3234if (_rChild) _rChild->append_components(locals, components, tmpdef_flag);3235}32363237// Find the n'th base-operand in the match node,3238// recursively investigates match rules of user-defined operands.3239//3240// Implementation does not modify state of internal structures since they3241// can be shared.3242bool MatchNode::base_operand(uint &position, FormDict &globals,3243const char * &result, const char * &name,3244const char * &opType) const {3245assert (_name != NULL, "MatchNode::base_operand encountered empty node\n");3246// Base case3247if (_lChild==NULL && _rChild==NULL) {3248// Check for special case: "Universe", "label"3249if (strcmp(_opType,"Universe") == 0 || strcmp(_opType,"label")==0 ) {3250if (position == 0) {3251result = _result;3252name = _name;3253opType = _opType;3254return 1;3255} else {3256-- position;3257return 0;3258}3259}32603261const Form *form = globals[_opType];3262MatchNode *matchNode = NULL;3263// Check for user-defined type3264if (form) {3265// User operand or instruction?3266OperandForm *opForm = form->is_operand();3267InstructForm *inForm = form->is_instruction();3268if ( opForm ) {3269matchNode = (MatchNode*)opForm->_matrule;3270} else if ( inForm ) {3271matchNode = (MatchNode*)inForm->_matrule;3272}3273}3274// if this is user-defined, recurse on match rule3275// User-defined operand and instruction forms have a match-rule.3276if (matchNode) {3277return (matchNode->base_operand(position,globals,result,name,opType));3278} else {3279// Either not a form, or a system-defined form (no match rule).3280if (position==0) {3281result = _result;3282name = _name;3283opType = _opType;3284return 1;3285} else {3286--position;3287return 0;3288}3289}32903291} else {3292// Examine the left child and right child as well3293if (_lChild) {3294if (_lChild->base_operand(position, globals, result, name, opType))3295return 1;3296}32973298if (_rChild) {3299if (_rChild->base_operand(position, globals, result, name, opType))3300return 1;3301}3302}33033304return 0;3305}33063307// Recursive call on all operands' match rules in my match rule.3308uint MatchNode::num_consts(FormDict &globals) const {3309uint index = 0;3310uint num_consts = 0;3311const char *result;3312const char *name;3313const char *opType;33143315for (uint position = index;3316base_operand(position,globals,result,name,opType); position = index) {3317++index;3318if( ideal_to_const_type(opType) ) num_consts++;3319}33203321return num_consts;3322}33233324// Recursive call on all operands' match rules in my match rule.3325// Constants in match rule subtree with specified type3326uint MatchNode::num_consts(FormDict &globals, Form::DataType type) const {3327uint index = 0;3328uint num_consts = 0;3329const char *result;3330const char *name;3331const char *opType;33323333for (uint position = index;3334base_operand(position,globals,result,name,opType); position = index) {3335++index;3336if( ideal_to_const_type(opType) == type ) num_consts++;3337}33383339return num_consts;3340}33413342// Recursive call on all operands' match rules in my match rule.3343uint MatchNode::num_const_ptrs(FormDict &globals) const {3344return num_consts( globals, Form::idealP );3345}33463347bool MatchNode::sets_result() const {3348return ( (strcmp(_name,"Set") == 0) ? true : false );3349}33503351const char *MatchNode::reduce_right(FormDict &globals) const {3352// If there is no right reduction, return NULL.3353const char *rightStr = NULL;33543355// If we are a "Set", start from the right child.3356const MatchNode *const mnode = sets_result() ?3357(const MatchNode *)this->_rChild :3358(const MatchNode *)this;33593360// If our right child exists, it is the right reduction3361if ( mnode->_rChild ) {3362rightStr = mnode->_rChild->_internalop ? mnode->_rChild->_internalop3363: mnode->_rChild->_opType;3364}3365// Else, May be simple chain rule: (Set dst operand_form), rightStr=NULL;3366return rightStr;3367}33683369const char *MatchNode::reduce_left(FormDict &globals) const {3370// If there is no left reduction, return NULL.3371const char *leftStr = NULL;33723373// If we are a "Set", start from the right child.3374const MatchNode *const mnode = sets_result() ?3375(const MatchNode *)this->_rChild :3376(const MatchNode *)this;33773378// If our left child exists, it is the left reduction3379if ( mnode->_lChild ) {3380leftStr = mnode->_lChild->_internalop ? mnode->_lChild->_internalop3381: mnode->_lChild->_opType;3382} else {3383// May be simple chain rule: (Set dst operand_form_source)3384if ( sets_result() ) {3385OperandForm *oper = globals[mnode->_opType]->is_operand();3386if( oper ) {3387leftStr = mnode->_opType;3388}3389}3390}3391return leftStr;3392}33933394//------------------------------count_instr_names------------------------------3395// Count occurrences of operands names in the leaves of the instruction3396// match rule.3397void MatchNode::count_instr_names( Dict &names ) {3398if( !this ) return;3399if( _lChild ) _lChild->count_instr_names(names);3400if( _rChild ) _rChild->count_instr_names(names);3401if( !_lChild && !_rChild ) {3402uintptr_t cnt = (uintptr_t)names[_name];3403cnt++; // One more name found3404names.Insert(_name,(void*)cnt);3405}3406}34073408//------------------------------build_instr_pred-------------------------------3409// Build a path to 'name' in buf. Actually only build if cnt is zero, so we3410// can skip some leading instances of 'name'.3411int MatchNode::build_instr_pred( char *buf, const char *name, int cnt ) {3412if( _lChild ) {3413if( !cnt ) strcpy( buf, "_kids[0]->" );3414cnt = _lChild->build_instr_pred( buf+strlen(buf), name, cnt );3415if( cnt < 0 ) return cnt; // Found it, all done3416}3417if( _rChild ) {3418if( !cnt ) strcpy( buf, "_kids[1]->" );3419cnt = _rChild->build_instr_pred( buf+strlen(buf), name, cnt );3420if( cnt < 0 ) return cnt; // Found it, all done3421}3422if( !_lChild && !_rChild ) { // Found a leaf3423// Wrong name? Give up...3424if( strcmp(name,_name) ) return cnt;3425if( !cnt ) strcpy(buf,"_leaf");3426return cnt-1;3427}3428return cnt;3429}343034313432//------------------------------build_internalop-------------------------------3433// Build string representation of subtree3434void MatchNode::build_internalop( ) {3435char *iop, *subtree;3436const char *lstr, *rstr;3437// Build string representation of subtree3438// Operation lchildType rchildType3439int len = (int)strlen(_opType) + 4;3440lstr = (_lChild) ? ((_lChild->_internalop) ?3441_lChild->_internalop : _lChild->_opType) : "";3442rstr = (_rChild) ? ((_rChild->_internalop) ?3443_rChild->_internalop : _rChild->_opType) : "";3444len += (int)strlen(lstr) + (int)strlen(rstr);3445subtree = (char *)malloc(len);3446sprintf(subtree,"_%s_%s_%s", _opType, lstr, rstr);3447// Hash the subtree string in _internalOps; if a name exists, use it3448iop = (char *)_AD._internalOps[subtree];3449// Else create a unique name, and add it to the hash table3450if (iop == NULL) {3451iop = subtree;3452_AD._internalOps.Insert(subtree, iop);3453_AD._internalOpNames.addName(iop);3454_AD._internalMatch.Insert(iop, this);3455}3456// Add the internal operand name to the MatchNode3457_internalop = iop;3458_result = iop;3459}346034613462void MatchNode::dump() {3463output(stderr);3464}34653466void MatchNode::output(FILE *fp) {3467if (_lChild==0 && _rChild==0) {3468fprintf(fp," %s",_name); // operand3469}3470else {3471fprintf(fp," (%s ",_name); // " (opcodeName "3472if(_lChild) _lChild->output(fp); // left operand3473if(_rChild) _rChild->output(fp); // right operand3474fprintf(fp,")"); // ")"3475}3476}34773478int MatchNode::needs_ideal_memory_edge(FormDict &globals) const {3479static const char *needs_ideal_memory_list[] = {3480"StoreI","StoreL","StoreP","StoreN","StoreNKlass","StoreD","StoreF" ,3481"StoreB","StoreC","Store" ,"StoreFP",3482"LoadI", "LoadL", "LoadP" ,"LoadN", "LoadD" ,"LoadF" ,3483"LoadB" , "LoadUB", "LoadUS" ,"LoadS" ,"Load" ,3484"StoreVector", "LoadVector",3485"LoadRange", "LoadKlass", "LoadNKlass", "LoadL_unaligned", "LoadD_unaligned",3486"LoadPLocked",3487"StorePConditional", "StoreIConditional", "StoreLConditional",3488"CompareAndSwapI", "CompareAndSwapL", "CompareAndSwapP", "CompareAndSwapN",3489"StoreCM",3490"ClearArray",3491"GetAndAddI", "GetAndSetI", "GetAndSetP",3492"GetAndAddL", "GetAndSetL", "GetAndSetN",3493};3494int cnt = sizeof(needs_ideal_memory_list)/sizeof(char*);3495if( strcmp(_opType,"PrefetchRead")==0 ||3496strcmp(_opType,"PrefetchWrite")==0 ||3497strcmp(_opType,"PrefetchAllocation")==0 )3498return 1;3499if( _lChild ) {3500const char *opType = _lChild->_opType;3501for( int i=0; i<cnt; i++ )3502if( strcmp(opType,needs_ideal_memory_list[i]) == 0 )3503return 1;3504if( _lChild->needs_ideal_memory_edge(globals) )3505return 1;3506}3507if( _rChild ) {3508const char *opType = _rChild->_opType;3509for( int i=0; i<cnt; i++ )3510if( strcmp(opType,needs_ideal_memory_list[i]) == 0 )3511return 1;3512if( _rChild->needs_ideal_memory_edge(globals) )3513return 1;3514}35153516return 0;3517}35183519// TRUE if defines a derived oop, and so needs a base oop edge present3520// post-matching.3521int MatchNode::needs_base_oop_edge() const {3522if( !strcmp(_opType,"AddP") ) return 1;3523if( strcmp(_opType,"Set") ) return 0;3524return !strcmp(_rChild->_opType,"AddP");3525}35263527int InstructForm::needs_base_oop_edge(FormDict &globals) const {3528if( is_simple_chain_rule(globals) ) {3529const char *src = _matrule->_rChild->_opType;3530OperandForm *src_op = globals[src]->is_operand();3531assert( src_op, "Not operand class of chain rule" );3532return src_op->_matrule ? src_op->_matrule->needs_base_oop_edge() : 0;3533} // Else check instruction35343535return _matrule ? _matrule->needs_base_oop_edge() : 0;3536}353735383539//-------------------------cisc spilling methods-------------------------------3540// helper routines and methods for detecting cisc-spilling instructions3541//-------------------------cisc_spill_merge------------------------------------3542int MatchNode::cisc_spill_merge(int left_spillable, int right_spillable) {3543int cisc_spillable = Maybe_cisc_spillable;35443545// Combine results of left and right checks3546if( (left_spillable == Maybe_cisc_spillable) && (right_spillable == Maybe_cisc_spillable) ) {3547// neither side is spillable, nor prevents cisc spilling3548cisc_spillable = Maybe_cisc_spillable;3549}3550else if( (left_spillable == Maybe_cisc_spillable) && (right_spillable > Maybe_cisc_spillable) ) {3551// right side is spillable3552cisc_spillable = right_spillable;3553}3554else if( (right_spillable == Maybe_cisc_spillable) && (left_spillable > Maybe_cisc_spillable) ) {3555// left side is spillable3556cisc_spillable = left_spillable;3557}3558else if( (left_spillable == Not_cisc_spillable) || (right_spillable == Not_cisc_spillable) ) {3559// left or right prevents cisc spilling this instruction3560cisc_spillable = Not_cisc_spillable;3561}3562else {3563// Only allow one to spill3564cisc_spillable = Not_cisc_spillable;3565}35663567return cisc_spillable;3568}35693570//-------------------------root_ops_match--------------------------------------3571bool static root_ops_match(FormDict &globals, const char *op1, const char *op2) {3572// Base Case: check that the current operands/operations match3573assert( op1, "Must have op's name");3574assert( op2, "Must have op's name");3575const Form *form1 = globals[op1];3576const Form *form2 = globals[op2];35773578return (form1 == form2);3579}35803581//-------------------------cisc_spill_match_node-------------------------------3582// Recursively check two MatchRules for legal conversion via cisc-spilling3583int MatchNode::cisc_spill_match(FormDict& globals, RegisterForm* registers, MatchNode* mRule2, const char* &operand, const char* ®_type) {3584int cisc_spillable = Maybe_cisc_spillable;3585int left_spillable = Maybe_cisc_spillable;3586int right_spillable = Maybe_cisc_spillable;35873588// Check that each has same number of operands at this level3589if( (_lChild && !(mRule2->_lChild)) || (_rChild && !(mRule2->_rChild)) )3590return Not_cisc_spillable;35913592// Base Case: check that the current operands/operations match3593// or are CISC spillable3594assert( _opType, "Must have _opType");3595assert( mRule2->_opType, "Must have _opType");3596const Form *form = globals[_opType];3597const Form *form2 = globals[mRule2->_opType];3598if( form == form2 ) {3599cisc_spillable = Maybe_cisc_spillable;3600} else {3601const InstructForm *form2_inst = form2 ? form2->is_instruction() : NULL;3602const char *name_left = mRule2->_lChild ? mRule2->_lChild->_opType : NULL;3603const char *name_right = mRule2->_rChild ? mRule2->_rChild->_opType : NULL;3604DataType data_type = Form::none;3605if (form->is_operand()) {3606// Make sure the loadX matches the type of the reg3607data_type = form->ideal_to_Reg_type(form->is_operand()->ideal_type(globals));3608}3609// Detect reg vs (loadX memory)3610if( form->is_cisc_reg(globals)3611&& form2_inst3612&& data_type != Form::none3613&& (is_load_from_memory(mRule2->_opType) == data_type) // reg vs. (load memory)3614&& (name_left != NULL) // NOT (load)3615&& (name_right == NULL) ) { // NOT (load memory foo)3616const Form *form2_left = name_left ? globals[name_left] : NULL;3617if( form2_left && form2_left->is_cisc_mem(globals) ) {3618cisc_spillable = Is_cisc_spillable;3619operand = _name;3620reg_type = _result;3621return Is_cisc_spillable;3622} else {3623cisc_spillable = Not_cisc_spillable;3624}3625}3626// Detect reg vs memory3627else if( form->is_cisc_reg(globals) && form2->is_cisc_mem(globals) ) {3628cisc_spillable = Is_cisc_spillable;3629operand = _name;3630reg_type = _result;3631return Is_cisc_spillable;3632} else {3633cisc_spillable = Not_cisc_spillable;3634}3635}36363637// If cisc is still possible, check rest of tree3638if( cisc_spillable == Maybe_cisc_spillable ) {3639// Check that each has same number of operands at this level3640if( (_lChild && !(mRule2->_lChild)) || (_rChild && !(mRule2->_rChild)) ) return Not_cisc_spillable;36413642// Check left operands3643if( (_lChild == NULL) && (mRule2->_lChild == NULL) ) {3644left_spillable = Maybe_cisc_spillable;3645} else {3646left_spillable = _lChild->cisc_spill_match(globals, registers, mRule2->_lChild, operand, reg_type);3647}36483649// Check right operands3650if( (_rChild == NULL) && (mRule2->_rChild == NULL) ) {3651right_spillable = Maybe_cisc_spillable;3652} else {3653right_spillable = _rChild->cisc_spill_match(globals, registers, mRule2->_rChild, operand, reg_type);3654}36553656// Combine results of left and right checks3657cisc_spillable = cisc_spill_merge(left_spillable, right_spillable);3658}36593660return cisc_spillable;3661}36623663//---------------------------cisc_spill_match_rule------------------------------3664// Recursively check two MatchRules for legal conversion via cisc-spilling3665// This method handles the root of Match tree,3666// general recursive checks done in MatchNode3667int MatchRule::matchrule_cisc_spill_match(FormDict& globals, RegisterForm* registers,3668MatchRule* mRule2, const char* &operand,3669const char* ®_type) {3670int cisc_spillable = Maybe_cisc_spillable;3671int left_spillable = Maybe_cisc_spillable;3672int right_spillable = Maybe_cisc_spillable;36733674// Check that each sets a result3675if( !(sets_result() && mRule2->sets_result()) ) return Not_cisc_spillable;3676// Check that each has same number of operands at this level3677if( (_lChild && !(mRule2->_lChild)) || (_rChild && !(mRule2->_rChild)) ) return Not_cisc_spillable;36783679// Check left operands: at root, must be target of 'Set'3680if( (_lChild == NULL) || (mRule2->_lChild == NULL) ) {3681left_spillable = Not_cisc_spillable;3682} else {3683// Do not support cisc-spilling instruction's target location3684if( root_ops_match(globals, _lChild->_opType, mRule2->_lChild->_opType) ) {3685left_spillable = Maybe_cisc_spillable;3686} else {3687left_spillable = Not_cisc_spillable;3688}3689}36903691// Check right operands: recursive walk to identify reg->mem operand3692if( (_rChild == NULL) && (mRule2->_rChild == NULL) ) {3693right_spillable = Maybe_cisc_spillable;3694} else {3695right_spillable = _rChild->cisc_spill_match(globals, registers, mRule2->_rChild, operand, reg_type);3696}36973698// Combine results of left and right checks3699cisc_spillable = cisc_spill_merge(left_spillable, right_spillable);37003701return cisc_spillable;3702}37033704//----------------------------- equivalent ------------------------------------3705// Recursively check to see if two match rules are equivalent.3706// This rule handles the root.3707bool MatchRule::equivalent(FormDict &globals, MatchNode *mRule2) {3708// Check that each sets a result3709if (sets_result() != mRule2->sets_result()) {3710return false;3711}37123713// Check that the current operands/operations match3714assert( _opType, "Must have _opType");3715assert( mRule2->_opType, "Must have _opType");3716const Form *form = globals[_opType];3717const Form *form2 = globals[mRule2->_opType];3718if( form != form2 ) {3719return false;3720}37213722if (_lChild ) {3723if( !_lChild->equivalent(globals, mRule2->_lChild) )3724return false;3725} else if (mRule2->_lChild) {3726return false; // I have NULL left child, mRule2 has non-NULL left child.3727}37283729if (_rChild ) {3730if( !_rChild->equivalent(globals, mRule2->_rChild) )3731return false;3732} else if (mRule2->_rChild) {3733return false; // I have NULL right child, mRule2 has non-NULL right child.3734}37353736// We've made it through the gauntlet.3737return true;3738}37393740//----------------------------- equivalent ------------------------------------3741// Recursively check to see if two match rules are equivalent.3742// This rule handles the operands.3743bool MatchNode::equivalent(FormDict &globals, MatchNode *mNode2) {3744if( !mNode2 )3745return false;37463747// Check that the current operands/operations match3748assert( _opType, "Must have _opType");3749assert( mNode2->_opType, "Must have _opType");3750const Form *form = globals[_opType];3751const Form *form2 = globals[mNode2->_opType];3752if( form != form2 ) {3753return false;3754}37553756// Check that their children also match3757if (_lChild ) {3758if( !_lChild->equivalent(globals, mNode2->_lChild) )3759return false;3760} else if (mNode2->_lChild) {3761return false; // I have NULL left child, mNode2 has non-NULL left child.3762}37633764if (_rChild ) {3765if( !_rChild->equivalent(globals, mNode2->_rChild) )3766return false;3767} else if (mNode2->_rChild) {3768return false; // I have NULL right child, mNode2 has non-NULL right child.3769}37703771// We've made it through the gauntlet.3772return true;3773}37743775//-------------------------- has_commutative_op -------------------------------3776// Recursively check for commutative operations with subtree operands3777// which could be swapped.3778void MatchNode::count_commutative_op(int& count) {3779static const char *commut_op_list[] = {3780"AddI","AddL","AddF","AddD",3781"AndI","AndL",3782"MaxI","MinI",3783"MulI","MulL","MulF","MulD",3784"OrI" ,"OrL" ,3785"XorI","XorL"3786};3787int cnt = sizeof(commut_op_list)/sizeof(char*);37883789if( _lChild && _rChild && (_lChild->_lChild || _rChild->_lChild) ) {3790// Don't swap if right operand is an immediate constant.3791bool is_const = false;3792if( _rChild->_lChild == NULL && _rChild->_rChild == NULL ) {3793FormDict &globals = _AD.globalNames();3794const Form *form = globals[_rChild->_opType];3795if ( form ) {3796OperandForm *oper = form->is_operand();3797if( oper && oper->interface_type(globals) == Form::constant_interface )3798is_const = true;3799}3800}3801if( !is_const ) {3802for( int i=0; i<cnt; i++ ) {3803if( strcmp(_opType, commut_op_list[i]) == 0 ) {3804count++;3805_commutative_id = count; // id should be > 03806break;3807}3808}3809}3810}3811if( _lChild )3812_lChild->count_commutative_op(count);3813if( _rChild )3814_rChild->count_commutative_op(count);3815}38163817//-------------------------- swap_commutative_op ------------------------------3818// Recursively swap specified commutative operation with subtree operands.3819void MatchNode::swap_commutative_op(bool atroot, int id) {3820if( _commutative_id == id ) { // id should be > 03821assert(_lChild && _rChild && (_lChild->_lChild || _rChild->_lChild ),3822"not swappable operation");3823MatchNode* tmp = _lChild;3824_lChild = _rChild;3825_rChild = tmp;3826// Don't exit here since we need to build internalop.3827}38283829bool is_set = ( strcmp(_opType, "Set") == 0 );3830if( _lChild )3831_lChild->swap_commutative_op(is_set, id);3832if( _rChild )3833_rChild->swap_commutative_op(is_set, id);38343835// If not the root, reduce this subtree to an internal operand3836if( !atroot && (_lChild || _rChild) ) {3837build_internalop();3838}3839}38403841//-------------------------- swap_commutative_op ------------------------------3842// Recursively swap specified commutative operation with subtree operands.3843void MatchRule::matchrule_swap_commutative_op(const char* instr_ident, int count, int& match_rules_cnt) {3844assert(match_rules_cnt < 100," too many match rule clones");3845// Clone3846MatchRule* clone = new MatchRule(_AD, this);3847// Swap operands of commutative operation3848((MatchNode*)clone)->swap_commutative_op(true, count);3849char* buf = (char*) malloc(strlen(instr_ident) + 4);3850sprintf(buf, "%s_%d", instr_ident, match_rules_cnt++);3851clone->_result = buf;38523853clone->_next = this->_next;3854this-> _next = clone;3855if( (--count) > 0 ) {3856this-> matchrule_swap_commutative_op(instr_ident, count, match_rules_cnt);3857clone->matchrule_swap_commutative_op(instr_ident, count, match_rules_cnt);3858}3859}38603861//------------------------------MatchRule--------------------------------------3862MatchRule::MatchRule(ArchDesc &ad)3863: MatchNode(ad), _depth(0), _construct(NULL), _numchilds(0) {3864_next = NULL;3865}38663867MatchRule::MatchRule(ArchDesc &ad, MatchRule* mRule)3868: MatchNode(ad, *mRule, 0), _depth(mRule->_depth),3869_construct(mRule->_construct), _numchilds(mRule->_numchilds) {3870_next = NULL;3871}38723873MatchRule::MatchRule(ArchDesc &ad, MatchNode* mroot, int depth, char *cnstr,3874int numleaves)3875: MatchNode(ad,*mroot), _depth(depth), _construct(cnstr),3876_numchilds(0) {3877_next = NULL;3878mroot->_lChild = NULL;3879mroot->_rChild = NULL;3880delete mroot;3881_numleaves = numleaves;3882_numchilds = (_lChild ? 1 : 0) + (_rChild ? 1 : 0);3883}3884MatchRule::~MatchRule() {3885}38863887// Recursive call collecting info on top-level operands, not transitive.3888// Implementation does not modify state of internal structures.3889void MatchRule::append_components(FormDict& locals, ComponentList& components, bool def_flag) const {3890assert (_name != NULL, "MatchNode::build_components encountered empty node\n");38913892MatchNode::append_components(locals, components,3893false /* not necessarily a def */);3894}38953896// Recursive call on all operands' match rules in my match rule.3897// Implementation does not modify state of internal structures since they3898// can be shared.3899// The MatchNode that is called first treats its3900bool MatchRule::base_operand(uint &position0, FormDict &globals,3901const char *&result, const char * &name,3902const char * &opType)const{3903uint position = position0;39043905return (MatchNode::base_operand( position, globals, result, name, opType));3906}390739083909bool MatchRule::is_base_register(FormDict &globals) const {3910uint position = 1;3911const char *result = NULL;3912const char *name = NULL;3913const char *opType = NULL;3914if (!base_operand(position, globals, result, name, opType)) {3915position = 0;3916if( base_operand(position, globals, result, name, opType) &&3917(strcmp(opType,"RegI")==0 ||3918strcmp(opType,"RegP")==0 ||3919strcmp(opType,"RegN")==0 ||3920strcmp(opType,"RegL")==0 ||3921strcmp(opType,"RegF")==0 ||3922strcmp(opType,"RegD")==0 ||3923strcmp(opType,"VecS")==0 ||3924strcmp(opType,"VecD")==0 ||3925strcmp(opType,"VecX")==0 ||3926strcmp(opType,"VecY")==0 ||3927strcmp(opType,"Reg" )==0) ) {3928return 1;3929}3930}3931return 0;3932}39333934Form::DataType MatchRule::is_base_constant(FormDict &globals) const {3935uint position = 1;3936const char *result = NULL;3937const char *name = NULL;3938const char *opType = NULL;3939if (!base_operand(position, globals, result, name, opType)) {3940position = 0;3941if (base_operand(position, globals, result, name, opType)) {3942return ideal_to_const_type(opType);3943}3944}3945return Form::none;3946}39473948bool MatchRule::is_chain_rule(FormDict &globals) const {39493950// Check for chain rule, and do not generate a match list for it3951if ((_lChild == NULL) && (_rChild == NULL) ) {3952const Form *form = globals[_opType];3953// If this is ideal, then it is a base match, not a chain rule.3954if ( form && form->is_operand() && (!form->ideal_only())) {3955return true;3956}3957}3958// Check for "Set" form of chain rule, and do not generate a match list3959if (_rChild) {3960const char *rch = _rChild->_opType;3961const Form *form = globals[rch];3962if ((!strcmp(_opType,"Set") &&3963((form) && form->is_operand()))) {3964return true;3965}3966}3967return false;3968}39693970int MatchRule::is_ideal_copy() const {3971if( _rChild ) {3972const char *opType = _rChild->_opType;3973#if 13974if( strcmp(opType,"CastIP")==0 )3975return 1;3976#else3977if( strcmp(opType,"CastII")==0 )3978return 1;3979// Do not treat *CastPP this way, because it3980// may transfer a raw pointer to an oop.3981// If the register allocator were to coalesce this3982// into a single LRG, the GC maps would be incorrect.3983//if( strcmp(opType,"CastPP")==0 )3984// return 1;3985//if( strcmp(opType,"CheckCastPP")==0 )3986// return 1;3987//3988// Do not treat CastX2P or CastP2X this way, because3989// raw pointers and int types are treated differently3990// when saving local & stack info for safepoints in3991// Output().3992//if( strcmp(opType,"CastX2P")==0 )3993// return 1;3994//if( strcmp(opType,"CastP2X")==0 )3995// return 1;3996#endif3997}3998if( is_chain_rule(_AD.globalNames()) &&3999_lChild && strncmp(_lChild->_opType,"stackSlot",9)==0 )4000return 1;4001return 0;4002}400340044005int MatchRule::is_expensive() const {4006if( _rChild ) {4007const char *opType = _rChild->_opType;4008if( strcmp(opType,"AtanD")==0 ||4009strcmp(opType,"CosD")==0 ||4010strcmp(opType,"DivD")==0 ||4011strcmp(opType,"DivF")==0 ||4012strcmp(opType,"DivI")==0 ||4013strcmp(opType,"ExpD")==0 ||4014strcmp(opType,"LogD")==0 ||4015strcmp(opType,"Log10D")==0 ||4016strcmp(opType,"ModD")==0 ||4017strcmp(opType,"ModF")==0 ||4018strcmp(opType,"ModI")==0 ||4019strcmp(opType,"PowD")==0 ||4020strcmp(opType,"SinD")==0 ||4021strcmp(opType,"SqrtD")==0 ||4022strcmp(opType,"TanD")==0 ||4023strcmp(opType,"ConvD2F")==0 ||4024strcmp(opType,"ConvD2I")==0 ||4025strcmp(opType,"ConvD2L")==0 ||4026strcmp(opType,"ConvF2D")==0 ||4027strcmp(opType,"ConvF2I")==0 ||4028strcmp(opType,"ConvF2L")==0 ||4029strcmp(opType,"ConvI2D")==0 ||4030strcmp(opType,"ConvI2F")==0 ||4031strcmp(opType,"ConvI2L")==0 ||4032strcmp(opType,"ConvL2D")==0 ||4033strcmp(opType,"ConvL2F")==0 ||4034strcmp(opType,"ConvL2I")==0 ||4035strcmp(opType,"DecodeN")==0 ||4036strcmp(opType,"EncodeP")==0 ||4037strcmp(opType,"EncodePKlass")==0 ||4038strcmp(opType,"DecodeNKlass")==0 ||4039strcmp(opType,"RoundDouble")==0 ||4040strcmp(opType,"RoundFloat")==0 ||4041strcmp(opType,"ReverseBytesI")==0 ||4042strcmp(opType,"ReverseBytesL")==0 ||4043strcmp(opType,"ReverseBytesUS")==0 ||4044strcmp(opType,"ReverseBytesS")==0 ||4045strcmp(opType,"ReplicateB")==0 ||4046strcmp(opType,"ReplicateS")==0 ||4047strcmp(opType,"ReplicateI")==0 ||4048strcmp(opType,"ReplicateL")==0 ||4049strcmp(opType,"ReplicateF")==0 ||4050strcmp(opType,"ReplicateD")==0 ||40510 /* 0 to line up columns nicely */ )4052return 1;4053}4054return 0;4055}40564057bool MatchRule::is_ideal_if() const {4058if( !_opType ) return false;4059return4060!strcmp(_opType,"If" ) ||4061!strcmp(_opType,"CountedLoopEnd");4062}40634064bool MatchRule::is_ideal_fastlock() const {4065if ( _opType && (strcmp(_opType,"Set") == 0) && _rChild ) {4066return (strcmp(_rChild->_opType,"FastLock") == 0);4067}4068return false;4069}40704071bool MatchRule::is_ideal_membar() const {4072if( !_opType ) return false;4073return4074!strcmp(_opType,"MemBarAcquire") ||4075!strcmp(_opType,"MemBarRelease") ||4076!strcmp(_opType,"MemBarAcquireLock") ||4077!strcmp(_opType,"MemBarReleaseLock") ||4078!strcmp(_opType,"LoadFence" ) ||4079!strcmp(_opType,"StoreFence") ||4080!strcmp(_opType,"MemBarVolatile") ||4081!strcmp(_opType,"MemBarCPUOrder") ||4082!strcmp(_opType,"MemBarStoreStore");4083}40844085bool MatchRule::is_ideal_loadPC() const {4086if ( _opType && (strcmp(_opType,"Set") == 0) && _rChild ) {4087return (strcmp(_rChild->_opType,"LoadPC") == 0);4088}4089return false;4090}40914092bool MatchRule::is_ideal_box() const {4093if ( _opType && (strcmp(_opType,"Set") == 0) && _rChild ) {4094return (strcmp(_rChild->_opType,"Box") == 0);4095}4096return false;4097}40984099bool MatchRule::is_ideal_goto() const {4100bool ideal_goto = false;41014102if( _opType && (strcmp(_opType,"Goto") == 0) ) {4103ideal_goto = true;4104}4105return ideal_goto;4106}41074108bool MatchRule::is_ideal_jump() const {4109if( _opType ) {4110if( !strcmp(_opType,"Jump") )4111return true;4112}4113return false;4114}41154116bool MatchRule::is_ideal_bool() const {4117if( _opType ) {4118if( !strcmp(_opType,"Bool") )4119return true;4120}4121return false;4122}412341244125Form::DataType MatchRule::is_ideal_load() const {4126Form::DataType ideal_load = Form::none;41274128if ( _opType && (strcmp(_opType,"Set") == 0) && _rChild ) {4129const char *opType = _rChild->_opType;4130ideal_load = is_load_from_memory(opType);4131}41324133return ideal_load;4134}41354136bool MatchRule::is_vector() const {4137static const char *vector_list[] = {4138"AddVB","AddVS","AddVI","AddVL","AddVF","AddVD",4139"SubVB","SubVS","SubVI","SubVL","SubVF","SubVD",4140"MulVS","MulVI","MulVF","MulVD",4141"DivVF","DivVD",4142"AndV" ,"XorV" ,"OrV",4143"LShiftCntV","RShiftCntV",4144"LShiftVB","LShiftVS","LShiftVI","LShiftVL",4145"RShiftVB","RShiftVS","RShiftVI","RShiftVL",4146"URShiftVB","URShiftVS","URShiftVI","URShiftVL",4147"ReplicateB","ReplicateS","ReplicateI","ReplicateL","ReplicateF","ReplicateD",4148"LoadVector","StoreVector",4149// Next are not supported currently.4150"PackB","PackS","PackI","PackL","PackF","PackD","Pack2L","Pack2D",4151"ExtractB","ExtractUB","ExtractC","ExtractS","ExtractI","ExtractL","ExtractF","ExtractD"4152};4153int cnt = sizeof(vector_list)/sizeof(char*);4154if (_rChild) {4155const char *opType = _rChild->_opType;4156for (int i=0; i<cnt; i++)4157if (strcmp(opType,vector_list[i]) == 0)4158return true;4159}4160return false;4161}416241634164bool MatchRule::skip_antidep_check() const {4165// Some loads operate on what is effectively immutable memory so we4166// should skip the anti dep computations. For some of these nodes4167// the rewritable field keeps the anti dep logic from triggering but4168// for certain kinds of LoadKlass it does not since they are4169// actually reading memory which could be rewritten by the runtime,4170// though never by generated code. This disables it uniformly for4171// the nodes that behave like this: LoadKlass, LoadNKlass and4172// LoadRange.4173if ( _opType && (strcmp(_opType,"Set") == 0) && _rChild ) {4174const char *opType = _rChild->_opType;4175if (strcmp("LoadKlass", opType) == 0 ||4176strcmp("LoadNKlass", opType) == 0 ||4177strcmp("LoadRange", opType) == 0) {4178return true;4179}4180}41814182return false;4183}418441854186Form::DataType MatchRule::is_ideal_store() const {4187Form::DataType ideal_store = Form::none;41884189if ( _opType && (strcmp(_opType,"Set") == 0) && _rChild ) {4190const char *opType = _rChild->_opType;4191ideal_store = is_store_to_memory(opType);4192}41934194return ideal_store;4195}419641974198void MatchRule::dump() {4199output(stderr);4200}42014202// Write just one line.4203void MatchRule::output_short(FILE *fp) {4204fprintf(fp,"MatchRule: ( %s",_name);4205if (_lChild) _lChild->output(fp);4206if (_rChild) _rChild->output(fp);4207fprintf(fp," )");4208}42094210void MatchRule::output(FILE *fp) {4211output_short(fp);4212fprintf(fp,"\n nesting depth = %d\n", _depth);4213if (_result) fprintf(fp," Result Type = %s", _result);4214fprintf(fp,"\n");4215}42164217//------------------------------Attribute--------------------------------------4218Attribute::Attribute(char *id, char* val, int type)4219: _ident(id), _val(val), _atype(type) {4220}4221Attribute::~Attribute() {4222}42234224int Attribute::int_val(ArchDesc &ad) {4225// Make sure it is an integer constant:4226int result = 0;4227if (!_val || !ADLParser::is_int_token(_val, result)) {4228ad.syntax_err(0, "Attribute %s must have an integer value: %s",4229_ident, _val ? _val : "");4230}4231return result;4232}42334234void Attribute::dump() {4235output(stderr);4236} // Debug printer42374238// Write to output files4239void Attribute::output(FILE *fp) {4240fprintf(fp,"Attribute: %s %s\n", (_ident?_ident:""), (_val?_val:""));4241}42424243//------------------------------FormatRule----------------------------------4244FormatRule::FormatRule(char *temp)4245: _temp(temp) {4246}4247FormatRule::~FormatRule() {4248}42494250void FormatRule::dump() {4251output(stderr);4252}42534254// Write to output files4255void FormatRule::output(FILE *fp) {4256fprintf(fp,"\nFormat Rule: \n%s", (_temp?_temp:""));4257fprintf(fp,"\n");4258}425942604261