Path: blob/master/src/hotspot/share/adlc/formsopt.cpp
41145 views
/*1* Copyright (c) 1998, 2012, 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 "adlc.hpp"2627//==============================Register Allocation============================28int RegisterForm::_reg_ctr = 0;2930//------------------------------RegisterForm-----------------------------------31// Constructor32RegisterForm::RegisterForm()33: _regDef(cmpstr,hashstr, Form::arena),34_regClass(cmpstr,hashstr, Form::arena),35_allocClass(cmpstr,hashstr, Form::arena) {36}37RegisterForm::~RegisterForm() {38}3940// record a new register definition41void RegisterForm::addRegDef(char *name, char *callingConv, char *c_conv,42char *idealtype, char *encoding, char* concrete) {43RegDef *regDef = new RegDef(name, callingConv, c_conv, idealtype, encoding, concrete);44_rdefs.addName(name);45_regDef.Insert(name,regDef);46}4748// record a new register class49template <typename T>50T* RegisterForm::addRegClass(const char* className) {51T* regClass = new T(className);52_rclasses.addName(className);53_regClass.Insert(className, regClass);54return regClass;55}5657// Explicit instantiation for all supported register classes.58template RegClass* RegisterForm::addRegClass<RegClass>(const char* className);59template CodeSnippetRegClass* RegisterForm::addRegClass<CodeSnippetRegClass>(const char* className);60template ConditionalRegClass* RegisterForm::addRegClass<ConditionalRegClass>(const char* className);6162// record a new register class63AllocClass *RegisterForm::addAllocClass(char *className) {64AllocClass *allocClass = new AllocClass(className);65_aclasses.addName(className);66_allocClass.Insert(className,allocClass);67return allocClass;68}6970// Called after parsing the Register block. Record the register class71// for spill-slots/regs.72void RegisterForm::addSpillRegClass() {73// Stack slots start at the next available even register number.74_reg_ctr = (_reg_ctr+7) & ~7;75const char *rc_name = "stack_slots";76RegClass* reg_class = new RegClass(rc_name);77reg_class->set_stack_version(true);78_rclasses.addName(rc_name);79_regClass.Insert(rc_name,reg_class);80}8182// Called after parsing the Register block. Record the register class83// for operands which are overwritten after matching.84void RegisterForm::addDynamicRegClass() {85const char *rc_name = "dynamic";86RegClass* reg_class = new RegClass(rc_name);87reg_class->set_stack_version(false);88_rclasses.addName(rc_name);89_regClass.Insert(rc_name,reg_class);90}9192// Provide iteration over all register definitions93// in the order used by the register allocator94void RegisterForm::reset_RegDefs() {95_current_ac = NULL;96_aclasses.reset();97}9899RegDef *RegisterForm::iter_RegDefs() {100// Check if we need to get the next AllocClass101if ( _current_ac == NULL ) {102const char *ac_name = _aclasses.iter();103if( ac_name == NULL ) return NULL; // No more allocation classes104_current_ac = (AllocClass*)_allocClass[ac_name];105_current_ac->_regDefs.reset();106assert( _current_ac != NULL, "Name must match an allocation class");107}108109const char *rd_name = _current_ac->_regDefs.iter();110if( rd_name == NULL ) {111// At end of this allocation class, check the next112_current_ac = NULL;113return iter_RegDefs();114}115RegDef *reg_def = (RegDef*)_current_ac->_regDef[rd_name];116assert( reg_def != NULL, "Name must match a register definition");117return reg_def;118}119120// return the register definition with name 'regName'121RegDef *RegisterForm::getRegDef(const char *regName) {122RegDef *regDef = (RegDef*)_regDef[regName];123return regDef;124}125126// return the register class with name 'className'127RegClass *RegisterForm::getRegClass(const char *className) {128RegClass *regClass = (RegClass*)_regClass[className];129return regClass;130}131132133// Check that register classes are compatible with chunks134bool RegisterForm::verify() {135bool valid = true;136137// Verify Register Classes138// check that each register class contains registers from one chunk139const char *rc_name = NULL;140_rclasses.reset();141while ( (rc_name = _rclasses.iter()) != NULL ) {142// Check the chunk value for all registers in this class143RegClass *reg_class = getRegClass(rc_name);144assert( reg_class != NULL, "InternalError() no matching register class");145} // end of RegClasses146147// Verify that every register has been placed into an allocation class148RegDef *reg_def = NULL;149reset_RegDefs();150uint num_register_zero = 0;151while ( (reg_def = iter_RegDefs()) != NULL ) {152if( reg_def->register_num() == 0 ) ++num_register_zero;153}154if( num_register_zero > 1 ) {155fprintf(stderr,156"ERROR: More than one register has been assigned register-number 0.\n"157"Probably because a register has not been entered into an allocation class.\n");158}159160return valid;161}162163// Compute RegMask size164int RegisterForm::RegMask_Size() {165// Need at least this many words166int words_for_regs = (_reg_ctr + 31)>>5;167// The array of Register Mask bits should be large enough to cover168// all the machine registers and all parameters that need to be passed169// on the stack (stack registers) up to some interesting limit. Methods170// that need more parameters will NOT be compiled. On Intel, the limit171// is something like 90+ parameters.172// Add a few (3 words == 96 bits) for incoming & outgoing arguments to calls.173// Round up to the next doubleword size.174return (words_for_regs + 3 + 1) & ~1;175}176177void RegisterForm::dump() { // Debug printer178output(stderr);179}180181void RegisterForm::output(FILE *fp) { // Write info to output files182const char *name;183fprintf(fp,"\n");184fprintf(fp,"-------------------- Dump RegisterForm --------------------\n");185for(_rdefs.reset(); (name = _rdefs.iter()) != NULL;) {186((RegDef*)_regDef[name])->output(fp);187}188fprintf(fp,"\n");189for (_rclasses.reset(); (name = _rclasses.iter()) != NULL;) {190((RegClass*)_regClass[name])->output(fp);191}192fprintf(fp,"\n");193for (_aclasses.reset(); (name = _aclasses.iter()) != NULL;) {194((AllocClass*)_allocClass[name])->output(fp);195}196fprintf(fp,"-------------------- end RegisterForm --------------------\n");197}198199//------------------------------RegDef-----------------------------------------200// Constructor201RegDef::RegDef(char *regname, char *callconv, char *c_conv, char * idealtype, char * encode, char * concrete)202: _regname(regname), _callconv(callconv), _c_conv(c_conv),203_idealtype(idealtype),204_register_encode(encode),205_concrete(concrete),206_register_num(0) {207208// Chunk and register mask are determined by the register number209// _register_num is set when registers are added to an allocation class210}211RegDef::~RegDef() { // Destructor212}213214void RegDef::set_register_num(uint32 register_num) {215_register_num = register_num;216}217218// Bit pattern used for generating machine code219const char* RegDef::register_encode() const {220return _register_encode;221}222223// Register number used in machine-independent code224uint32 RegDef::register_num() const {225return _register_num;226}227228void RegDef::dump() {229output(stderr);230}231232void RegDef::output(FILE *fp) { // Write info to output files233fprintf(fp,"RegDef: %s (%s) encode as %s using number %d\n",234_regname, (_callconv?_callconv:""), _register_encode, _register_num);235fprintf(fp,"\n");236}237238239//------------------------------RegClass---------------------------------------240// Construct a register class into which registers will be inserted241RegClass::RegClass(const char* classid) : _stack_or_reg(false), _classid(classid), _regDef(cmpstr, hashstr, Form::arena) {242}243244RegClass::~RegClass() {245}246247// record a register in this class248void RegClass::addReg(RegDef *regDef) {249_regDefs.addName(regDef->_regname);250_regDef.Insert((void*)regDef->_regname, regDef);251}252253// Number of registers in class254uint RegClass::size() const {255return _regDef.Size();256}257258const RegDef *RegClass::get_RegDef(const char *rd_name) const {259return (const RegDef*)_regDef[rd_name];260}261262void RegClass::reset() {263_regDefs.reset();264}265266const char *RegClass::rd_name_iter() {267return _regDefs.iter();268}269270RegDef *RegClass::RegDef_iter() {271const char *rd_name = rd_name_iter();272RegDef *reg_def = rd_name ? (RegDef*)_regDef[rd_name] : NULL;273return reg_def;274}275276const RegDef* RegClass::find_first_elem() {277const RegDef* first = NULL;278const RegDef* def = NULL;279280reset();281while ((def = RegDef_iter()) != NULL) {282if (first == NULL || def->register_num() < first->register_num()) {283first = def;284}285}286287assert(first != NULL, "empty mask?");288return first;;289}290291// Collect all the registers in this register-word. One bit per register.292int RegClass::regs_in_word( int wordnum, bool stack_also ) {293int word = 0;294const char *name;295for(_regDefs.reset(); (name = _regDefs.iter()) != NULL;) {296int rnum = ((RegDef*)_regDef[name])->register_num();297if( (rnum >> 5) == wordnum )298word |= (1 << (rnum & 31));299}300if( stack_also ) {301// Now also collect stack bits302for( int i = 0; i < 32; i++ )303if( wordnum*32+i >= RegisterForm::_reg_ctr )304word |= (1 << i);305}306307return word;308}309310void RegClass::dump() {311output(stderr);312}313314void RegClass::output(FILE *fp) { // Write info to output files315fprintf(fp,"RegClass: %s\n",_classid);316const char *name;317for(_regDefs.reset(); (name = _regDefs.iter()) != NULL;) {318((RegDef*)_regDef[name])->output(fp);319}320fprintf(fp,"--- done with entries for reg_class %s\n\n",_classid);321}322323void RegClass::declare_register_masks(FILE* fp) {324const char* prefix = "";325const char* rc_name_to_upper = toUpper(_classid);326fprintf(fp, "extern const RegMask _%s%s_mask;\n", prefix, rc_name_to_upper);327fprintf(fp, "inline const RegMask &%s%s_mask() { return _%s%s_mask; }\n", prefix, rc_name_to_upper, prefix, rc_name_to_upper);328if (_stack_or_reg) {329fprintf(fp, "extern const RegMask _%sSTACK_OR_%s_mask;\n", prefix, rc_name_to_upper);330fprintf(fp, "inline const RegMask &%sSTACK_OR_%s_mask() { return _%sSTACK_OR_%s_mask; }\n", prefix, rc_name_to_upper, prefix, rc_name_to_upper);331}332delete[] rc_name_to_upper;333}334335void RegClass::build_register_masks(FILE* fp) {336int len = RegisterForm::RegMask_Size();337const char *prefix = "";338const char* rc_name_to_upper = toUpper(_classid);339fprintf(fp, "const RegMask _%s%s_mask(", prefix, rc_name_to_upper);340341int i;342for(i = 0; i < len - 1; i++) {343fprintf(fp," 0x%x,", regs_in_word(i, false));344}345fprintf(fp," 0x%x );\n", regs_in_word(i, false));346347if (_stack_or_reg) {348fprintf(fp, "const RegMask _%sSTACK_OR_%s_mask(", prefix, rc_name_to_upper);349for(i = 0; i < len - 1; i++) {350fprintf(fp," 0x%x,", regs_in_word(i, true));351}352fprintf(fp," 0x%x );\n", regs_in_word(i, true));353}354delete[] rc_name_to_upper;355}356357//------------------------------CodeSnippetRegClass---------------------------358CodeSnippetRegClass::CodeSnippetRegClass(const char* classid) : RegClass(classid), _code_snippet(NULL) {359}360361CodeSnippetRegClass::~CodeSnippetRegClass() {362delete _code_snippet;363}364365void CodeSnippetRegClass::declare_register_masks(FILE* fp) {366const char* prefix = "";367const char* rc_name_to_upper = toUpper(_classid);368fprintf(fp, "inline const RegMask &%s%s_mask() { %s }\n", prefix, rc_name_to_upper, _code_snippet);369delete[] rc_name_to_upper;370}371372//------------------------------ConditionalRegClass---------------------------373ConditionalRegClass::ConditionalRegClass(const char *classid) : RegClass(classid), _condition_code(NULL) {374}375376ConditionalRegClass::~ConditionalRegClass() {377delete _condition_code;378}379380void ConditionalRegClass::declare_register_masks(FILE* fp) {381const char* prefix = "";382const char* rc_name_to_upper = toUpper(_classid);383const char* rclass_0_to_upper = toUpper(_rclasses[0]->_classid);384const char* rclass_1_to_upper = toUpper(_rclasses[1]->_classid);385fprintf(fp, "inline const RegMask &%s%s_mask() {"386" return (%s) ?"387" %s%s_mask() :"388" %s%s_mask(); }\n",389prefix, rc_name_to_upper,390_condition_code,391prefix, rclass_0_to_upper,392prefix, rclass_1_to_upper);393if (_stack_or_reg) {394fprintf(fp, "inline const RegMask &%sSTACK_OR_%s_mask() {"395" return (%s) ?"396" %sSTACK_OR_%s_mask() :"397" %sSTACK_OR_%s_mask(); }\n",398prefix, rc_name_to_upper,399_condition_code,400prefix, rclass_0_to_upper,401prefix, rclass_1_to_upper);402}403delete[] rc_name_to_upper;404delete[] rclass_0_to_upper;405delete[] rclass_1_to_upper;406return;407}408409//------------------------------AllocClass-------------------------------------410AllocClass::AllocClass(char *classid) : _classid(classid), _regDef(cmpstr,hashstr, Form::arena) {411}412413// record a register in this class414void AllocClass::addReg(RegDef *regDef) {415assert( regDef != NULL, "Can not add a NULL to an allocation class");416regDef->set_register_num( RegisterForm::_reg_ctr++ );417// Add regDef to this allocation class418_regDefs.addName(regDef->_regname);419_regDef.Insert((void*)regDef->_regname, regDef);420}421422void AllocClass::dump() {423output(stderr);424}425426void AllocClass::output(FILE *fp) { // Write info to output files427fprintf(fp,"AllocClass: %s \n",_classid);428const char *name;429for(_regDefs.reset(); (name = _regDefs.iter()) != NULL;) {430((RegDef*)_regDef[name])->output(fp);431}432fprintf(fp,"--- done with entries for alloc_class %s\n\n",_classid);433}434435//==============================Frame Handling=================================436//------------------------------FrameForm--------------------------------------437FrameForm::FrameForm() {438_frame_pointer = NULL;439_c_frame_pointer = NULL;440_alignment = NULL;441_return_addr = NULL;442_c_return_addr = NULL;443_varargs_C_out_slots_killed = NULL;444_return_value = NULL;445_c_return_value = NULL;446_interpreter_frame_pointer_reg = NULL;447}448449FrameForm::~FrameForm() {450}451452void FrameForm::dump() {453output(stderr);454}455456void FrameForm::output(FILE *fp) { // Write info to output files457fprintf(fp,"\nFrame:\n");458}459460//==============================Scheduling=====================================461//------------------------------PipelineForm-----------------------------------462PipelineForm::PipelineForm()463: _reslist ()464, _resdict (cmpstr, hashstr, Form::arena)465, _classdict (cmpstr, hashstr, Form::arena)466, _rescount (0)467, _maxcycleused (0)468, _stages ()469, _stagecnt (0)470, _classlist ()471, _classcnt (0)472, _noplist ()473, _nopcnt (0)474, _variableSizeInstrs (false)475, _branchHasDelaySlot (false)476, _maxInstrsPerBundle (0)477, _maxBundlesPerCycle (1)478, _instrUnitSize (0)479, _bundleUnitSize (0)480, _instrFetchUnitSize (0)481, _instrFetchUnits (0) {482}483PipelineForm::~PipelineForm() {484}485486void PipelineForm::dump() {487output(stderr);488}489490void PipelineForm::output(FILE *fp) { // Write info to output files491const char *res;492const char *stage;493const char *cls;494const char *nop;495int count = 0;496497fprintf(fp,"\nPipeline:");498if (_variableSizeInstrs)499if (_instrUnitSize > 0)500fprintf(fp," variable-sized instructions in %d byte units", _instrUnitSize);501else502fprintf(fp," variable-sized instructions");503else504if (_instrUnitSize > 0)505fprintf(fp," fixed-sized instructions of %d bytes", _instrUnitSize);506else if (_bundleUnitSize > 0)507fprintf(fp," fixed-sized bundles of %d bytes", _bundleUnitSize);508else509fprintf(fp," fixed-sized instructions");510if (_branchHasDelaySlot)511fprintf(fp,", branch has delay slot");512if (_maxInstrsPerBundle > 0)513fprintf(fp,", max of %d instruction%s in parallel",514_maxInstrsPerBundle, _maxInstrsPerBundle > 1 ? "s" : "");515if (_maxBundlesPerCycle > 0)516fprintf(fp,", max of %d bundle%s in parallel",517_maxBundlesPerCycle, _maxBundlesPerCycle > 1 ? "s" : "");518if (_instrFetchUnitSize > 0 && _instrFetchUnits)519fprintf(fp, ", fetch %d x % d bytes per cycle", _instrFetchUnits, _instrFetchUnitSize);520521fprintf(fp,"\nResource:");522for ( _reslist.reset(); (res = _reslist.iter()) != NULL; )523fprintf(fp," %s(0x%08x)", res, _resdict[res]->is_resource()->mask());524fprintf(fp,"\n");525526fprintf(fp,"\nDescription:\n");527for ( _stages.reset(); (stage = _stages.iter()) != NULL; )528fprintf(fp," %s(%d)", stage, count++);529fprintf(fp,"\n");530531fprintf(fp,"\nClasses:\n");532for ( _classlist.reset(); (cls = _classlist.iter()) != NULL; )533_classdict[cls]->is_pipeclass()->output(fp);534535fprintf(fp,"\nNop Instructions:");536for ( _noplist.reset(); (nop = _noplist.iter()) != NULL; )537fprintf(fp, " \"%s\"", nop);538fprintf(fp,"\n");539}540541542//------------------------------ResourceForm-----------------------------------543ResourceForm::ResourceForm(unsigned resmask)544: _resmask(resmask) {545}546ResourceForm::~ResourceForm() {547}548549ResourceForm *ResourceForm::is_resource() const {550return (ResourceForm *)(this);551}552553void ResourceForm::dump() {554output(stderr);555}556557void ResourceForm::output(FILE *fp) { // Write info to output files558fprintf(fp, "resource: 0x%08x;\n", mask());559}560561562//------------------------------PipeClassOperandForm----------------------------------563564void PipeClassOperandForm::dump() {565output(stderr);566}567568void PipeClassOperandForm::output(FILE *fp) { // Write info to output files569fprintf(stderr,"PipeClassOperandForm: %s", _stage);570fflush(stderr);571if (_more_instrs > 0)572fprintf(stderr,"+%d", _more_instrs);573fprintf(stderr," (%s)\n", _iswrite ? "write" : "read");574fflush(stderr);575fprintf(fp,"PipeClassOperandForm: %s", _stage);576if (_more_instrs > 0)577fprintf(fp,"+%d", _more_instrs);578fprintf(fp," (%s)\n", _iswrite ? "write" : "read");579}580581582//------------------------------PipeClassResourceForm----------------------------------583584void PipeClassResourceForm::dump() {585output(stderr);586}587588void PipeClassResourceForm::output(FILE *fp) { // Write info to output files589fprintf(fp,"PipeClassResourceForm: %s at stage %s for %d cycles\n",590_resource, _stage, _cycles);591}592593594//------------------------------PipeClassForm----------------------------------595PipeClassForm::PipeClassForm(const char *id, int num)596: _ident(id)597, _num(num)598, _localNames(cmpstr, hashstr, Form::arena)599, _localUsage(cmpstr, hashstr, Form::arena)600, _has_fixed_latency(0)601, _fixed_latency(0)602, _instruction_count(0)603, _has_multiple_bundles(false)604, _has_branch_delay_slot(false)605, _force_serialization(false)606, _may_have_no_code(false) {607}608609PipeClassForm::~PipeClassForm() {610}611612PipeClassForm *PipeClassForm::is_pipeclass() const {613return (PipeClassForm *)(this);614}615616void PipeClassForm::dump() {617output(stderr);618}619620void PipeClassForm::output(FILE *fp) { // Write info to output files621fprintf(fp,"PipeClassForm: #%03d", _num);622if (_ident)623fprintf(fp," \"%s\":", _ident);624if (_has_fixed_latency)625fprintf(fp," latency %d", _fixed_latency);626if (_force_serialization)627fprintf(fp, ", force serialization");628if (_may_have_no_code)629fprintf(fp, ", may have no code");630fprintf(fp, ", %d instruction%s\n", InstructionCount(), InstructionCount() != 1 ? "s" : "");631}632633634//==============================Peephole Optimization==========================635int Peephole::_peephole_counter = 0;636//------------------------------Peephole---------------------------------------637Peephole::Peephole() : _match(NULL), _constraint(NULL), _replace(NULL), _next(NULL) {638_peephole_number = _peephole_counter++;639}640Peephole::~Peephole() {641}642643// Append a peephole rule with the same root instruction644void Peephole::append_peephole(Peephole *next_peephole) {645if( _next == NULL ) {646_next = next_peephole;647} else {648_next->append_peephole( next_peephole );649}650}651652// Store the components of this peephole rule653void Peephole::add_match(PeepMatch *match) {654assert( _match == NULL, "fatal()" );655_match = match;656}657658void Peephole::append_constraint(PeepConstraint *next_constraint) {659if( _constraint == NULL ) {660_constraint = next_constraint;661} else {662_constraint->append( next_constraint );663}664}665666void Peephole::add_replace(PeepReplace *replace) {667assert( _replace == NULL, "fatal()" );668_replace = replace;669}670671// class Peephole accessor methods are in the declaration.672673674void Peephole::dump() {675output(stderr);676}677678void Peephole::output(FILE *fp) { // Write info to output files679fprintf(fp,"Peephole:\n");680if( _match != NULL ) _match->output(fp);681if( _constraint != NULL ) _constraint->output(fp);682if( _replace != NULL ) _replace->output(fp);683// Output the next entry684if( _next ) _next->output(fp);685}686687//------------------------------PeepMatch--------------------------------------688PeepMatch::PeepMatch(char *rule) : _max_position(0), _rule(rule) {689}690PeepMatch::~PeepMatch() {691}692693694// Insert info into the match-rule695void PeepMatch::add_instruction(int parent, int position, const char *name,696int input) {697if( position > _max_position ) _max_position = position;698699_parent.addName((char*) (intptr_t) parent);700_position.addName((char*) (intptr_t) position);701_instrs.addName(name);702_input.addName((char*) (intptr_t) input);703}704705// Access info about instructions in the peep-match rule706int PeepMatch::max_position() {707return _max_position;708}709710const char *PeepMatch::instruction_name(int position) {711return _instrs.name(position);712}713714// Iterate through all info on matched instructions715void PeepMatch::reset() {716_parent.reset();717_position.reset();718_instrs.reset();719_input.reset();720}721722void PeepMatch::next_instruction(int &parent, int &position, const char* &name, int &input) {723parent = (int) (intptr_t) _parent.iter();724position = (int) (intptr_t) _position.iter();725name = _instrs.iter();726input = (int) (intptr_t) _input.iter();727}728729// 'true' if current position in iteration is a placeholder, not matched.730bool PeepMatch::is_placeholder() {731return _instrs.current_is_signal();732}733734735void PeepMatch::dump() {736output(stderr);737}738739void PeepMatch::output(FILE *fp) { // Write info to output files740fprintf(fp,"PeepMatch:\n");741}742743//------------------------------PeepConstraint---------------------------------744PeepConstraint::PeepConstraint(int left_inst, char* left_op, char* relation,745int right_inst, char* right_op)746: _left_inst(left_inst), _left_op(left_op), _relation(relation),747_right_inst(right_inst), _right_op(right_op), _next(NULL) {}748PeepConstraint::~PeepConstraint() {749}750751// Check if constraints use instruction at position752bool PeepConstraint::constrains_instruction(int position) {753// Check local instruction constraints754if( _left_inst == position ) return true;755if( _right_inst == position ) return true;756757// Check remaining constraints in list758if( _next == NULL ) return false;759else return _next->constrains_instruction(position);760}761762// Add another constraint763void PeepConstraint::append(PeepConstraint *next_constraint) {764if( _next == NULL ) {765_next = next_constraint;766} else {767_next->append( next_constraint );768}769}770771// Access the next constraint in the list772PeepConstraint *PeepConstraint::next() {773return _next;774}775776777void PeepConstraint::dump() {778output(stderr);779}780781void PeepConstraint::output(FILE *fp) { // Write info to output files782fprintf(fp,"PeepConstraint:\n");783}784785//------------------------------PeepReplace------------------------------------786PeepReplace::PeepReplace(char *rule) : _rule(rule) {787}788PeepReplace::~PeepReplace() {789}790791// Add contents of peepreplace792void PeepReplace::add_instruction(char *root) {793_instruction.addName(root);794_operand_inst_num.add_signal();795_operand_op_name.add_signal();796}797void PeepReplace::add_operand( int inst_num, char *inst_operand ) {798_instruction.add_signal();799_operand_inst_num.addName((char*) (intptr_t) inst_num);800_operand_op_name.addName(inst_operand);801}802803// Access contents of peepreplace804void PeepReplace::reset() {805_instruction.reset();806_operand_inst_num.reset();807_operand_op_name.reset();808}809void PeepReplace::next_instruction(const char* &inst){810inst = _instruction.iter();811int inst_num = (int) (intptr_t) _operand_inst_num.iter();812const char* inst_operand = _operand_op_name.iter();813}814void PeepReplace::next_operand(int &inst_num, const char* &inst_operand) {815const char* inst = _instruction.iter();816inst_num = (int) (intptr_t) _operand_inst_num.iter();817inst_operand = _operand_op_name.iter();818}819820821822void PeepReplace::dump() {823output(stderr);824}825826void PeepReplace::output(FILE *fp) { // Write info to output files827fprintf(fp,"PeepReplace:\n");828}829830831