Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/share/vm/adlc/formsopt.cpp
32285 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}818283// Provide iteration over all register definitions84// in the order used by the register allocator85void RegisterForm::reset_RegDefs() {86_current_ac = NULL;87_aclasses.reset();88}8990RegDef *RegisterForm::iter_RegDefs() {91// Check if we need to get the next AllocClass92if ( _current_ac == NULL ) {93const char *ac_name = _aclasses.iter();94if( ac_name == NULL ) return NULL; // No more allocation classes95_current_ac = (AllocClass*)_allocClass[ac_name];96_current_ac->_regDefs.reset();97assert( _current_ac != NULL, "Name must match an allocation class");98}99100const char *rd_name = _current_ac->_regDefs.iter();101if( rd_name == NULL ) {102// At end of this allocation class, check the next103_current_ac = NULL;104return iter_RegDefs();105}106RegDef *reg_def = (RegDef*)_current_ac->_regDef[rd_name];107assert( reg_def != NULL, "Name must match a register definition");108return reg_def;109}110111// return the register definition with name 'regName'112RegDef *RegisterForm::getRegDef(const char *regName) {113RegDef *regDef = (RegDef*)_regDef[regName];114return regDef;115}116117// return the register class with name 'className'118RegClass *RegisterForm::getRegClass(const char *className) {119RegClass *regClass = (RegClass*)_regClass[className];120return regClass;121}122123124// Check that register classes are compatible with chunks125bool RegisterForm::verify() {126bool valid = true;127128// Verify Register Classes129// check that each register class contains registers from one chunk130const char *rc_name = NULL;131_rclasses.reset();132while ( (rc_name = _rclasses.iter()) != NULL ) {133// Check the chunk value for all registers in this class134RegClass *reg_class = getRegClass(rc_name);135assert( reg_class != NULL, "InternalError() no matching register class");136} // end of RegClasses137138// Verify that every register has been placed into an allocation class139RegDef *reg_def = NULL;140reset_RegDefs();141uint num_register_zero = 0;142while ( (reg_def = iter_RegDefs()) != NULL ) {143if( reg_def->register_num() == 0 ) ++num_register_zero;144}145if( num_register_zero > 1 ) {146fprintf(stderr,147"ERROR: More than one register has been assigned register-number 0.\n"148"Probably because a register has not been entered into an allocation class.\n");149}150151return valid;152}153154// Compute RegMask size155int RegisterForm::RegMask_Size() {156// Need at least this many words157int words_for_regs = (_reg_ctr + 31)>>5;158// The array of Register Mask bits should be large enough to cover159// all the machine registers and all parameters that need to be passed160// on the stack (stack registers) up to some interesting limit. Methods161// that need more parameters will NOT be compiled. On Intel, the limit162// is something like 90+ parameters.163// Add a few (3 words == 96 bits) for incoming & outgoing arguments to calls.164// Round up to the next doubleword size.165return (words_for_regs + 3 + 1) & ~1;166}167168void RegisterForm::dump() { // Debug printer169output(stderr);170}171172void RegisterForm::output(FILE *fp) { // Write info to output files173const char *name;174fprintf(fp,"\n");175fprintf(fp,"-------------------- Dump RegisterForm --------------------\n");176for(_rdefs.reset(); (name = _rdefs.iter()) != NULL;) {177((RegDef*)_regDef[name])->output(fp);178}179fprintf(fp,"\n");180for (_rclasses.reset(); (name = _rclasses.iter()) != NULL;) {181((RegClass*)_regClass[name])->output(fp);182}183fprintf(fp,"\n");184for (_aclasses.reset(); (name = _aclasses.iter()) != NULL;) {185((AllocClass*)_allocClass[name])->output(fp);186}187fprintf(fp,"-------------------- end RegisterForm --------------------\n");188}189190//------------------------------RegDef-----------------------------------------191// Constructor192RegDef::RegDef(char *regname, char *callconv, char *c_conv, char * idealtype, char * encode, char * concrete)193: _regname(regname), _callconv(callconv), _c_conv(c_conv),194_idealtype(idealtype),195_register_encode(encode),196_concrete(concrete),197_register_num(0) {198199// Chunk and register mask are determined by the register number200// _register_num is set when registers are added to an allocation class201}202RegDef::~RegDef() { // Destructor203}204205void RegDef::set_register_num(uint32 register_num) {206_register_num = register_num;207}208209// Bit pattern used for generating machine code210const char* RegDef::register_encode() const {211return _register_encode;212}213214// Register number used in machine-independent code215uint32 RegDef::register_num() const {216return _register_num;217}218219void RegDef::dump() {220output(stderr);221}222223void RegDef::output(FILE *fp) { // Write info to output files224fprintf(fp,"RegDef: %s (%s) encode as %s using number %d\n",225_regname, (_callconv?_callconv:""), _register_encode, _register_num);226fprintf(fp,"\n");227}228229230//------------------------------RegClass---------------------------------------231// Construct a register class into which registers will be inserted232RegClass::RegClass(const char* classid) : _stack_or_reg(false), _classid(classid), _regDef(cmpstr, hashstr, Form::arena) {233}234235RegClass::~RegClass() {236delete _classid;237}238239// record a register in this class240void RegClass::addReg(RegDef *regDef) {241_regDefs.addName(regDef->_regname);242_regDef.Insert((void*)regDef->_regname, regDef);243}244245// Number of registers in class246uint RegClass::size() const {247return _regDef.Size();248}249250const RegDef *RegClass::get_RegDef(const char *rd_name) const {251return (const RegDef*)_regDef[rd_name];252}253254void RegClass::reset() {255_regDefs.reset();256}257258const char *RegClass::rd_name_iter() {259return _regDefs.iter();260}261262RegDef *RegClass::RegDef_iter() {263const char *rd_name = rd_name_iter();264RegDef *reg_def = rd_name ? (RegDef*)_regDef[rd_name] : NULL;265return reg_def;266}267268const RegDef* RegClass::find_first_elem() {269const RegDef* first = NULL;270const RegDef* def = NULL;271272reset();273while ((def = RegDef_iter()) != NULL) {274if (first == NULL || def->register_num() < first->register_num()) {275first = def;276}277}278279assert(first != NULL, "empty mask?");280return first;;281}282283// Collect all the registers in this register-word. One bit per register.284int RegClass::regs_in_word( int wordnum, bool stack_also ) {285int word = 0;286const char *name;287for(_regDefs.reset(); (name = _regDefs.iter()) != NULL;) {288int rnum = ((RegDef*)_regDef[name])->register_num();289if( (rnum >> 5) == wordnum )290word |= (1 << (rnum & 31));291}292if( stack_also ) {293// Now also collect stack bits294for( int i = 0; i < 32; i++ )295if( wordnum*32+i >= RegisterForm::_reg_ctr )296word |= (1 << i);297}298299return word;300}301302void RegClass::dump() {303output(stderr);304}305306void RegClass::output(FILE *fp) { // Write info to output files307fprintf(fp,"RegClass: %s\n",_classid);308const char *name;309for(_regDefs.reset(); (name = _regDefs.iter()) != NULL;) {310((RegDef*)_regDef[name])->output(fp);311}312fprintf(fp,"--- done with entries for reg_class %s\n\n",_classid);313}314315void RegClass::declare_register_masks(FILE* fp) {316const char* prefix = "";317const char* rc_name_to_upper = toUpper(_classid);318fprintf(fp, "extern const RegMask _%s%s_mask;\n", prefix, rc_name_to_upper);319fprintf(fp, "inline const RegMask &%s%s_mask() { return _%s%s_mask; }\n", prefix, rc_name_to_upper, prefix, rc_name_to_upper);320if (_stack_or_reg) {321fprintf(fp, "extern const RegMask _%sSTACK_OR_%s_mask;\n", prefix, rc_name_to_upper);322fprintf(fp, "inline const RegMask &%sSTACK_OR_%s_mask() { return _%sSTACK_OR_%s_mask; }\n", prefix, rc_name_to_upper, prefix, rc_name_to_upper);323}324delete[] rc_name_to_upper;325}326327void RegClass::build_register_masks(FILE* fp) {328int len = RegisterForm::RegMask_Size();329const char *prefix = "";330const char* rc_name_to_upper = toUpper(_classid);331fprintf(fp, "const RegMask _%s%s_mask(", prefix, rc_name_to_upper);332333int i;334for(i = 0; i < len - 1; i++) {335fprintf(fp," 0x%x,", regs_in_word(i, false));336}337fprintf(fp," 0x%x );\n", regs_in_word(i, false));338339if (_stack_or_reg) {340fprintf(fp, "const RegMask _%sSTACK_OR_%s_mask(", prefix, rc_name_to_upper);341for(i = 0; i < len - 1; i++) {342fprintf(fp," 0x%x,", regs_in_word(i, true));343}344fprintf(fp," 0x%x );\n", regs_in_word(i, true));345}346delete[] rc_name_to_upper;347}348349//------------------------------CodeSnippetRegClass---------------------------350CodeSnippetRegClass::CodeSnippetRegClass(const char* classid) : RegClass(classid), _code_snippet(NULL) {351}352353CodeSnippetRegClass::~CodeSnippetRegClass() {354delete _code_snippet;355}356357void CodeSnippetRegClass::declare_register_masks(FILE* fp) {358const char* prefix = "";359const char* rc_name_to_upper = toUpper(_classid);360fprintf(fp, "inline const RegMask &%s%s_mask() { %s }\n", prefix, rc_name_to_upper, _code_snippet);361delete[] rc_name_to_upper;362}363364//------------------------------ConditionalRegClass---------------------------365ConditionalRegClass::ConditionalRegClass(const char *classid) : RegClass(classid), _condition_code(NULL) {366}367368ConditionalRegClass::~ConditionalRegClass() {369delete _condition_code;370}371372void ConditionalRegClass::declare_register_masks(FILE* fp) {373const char* prefix = "";374const char* rc_name_to_upper = toUpper(_classid);375const char* rclass_0_to_upper = toUpper(_rclasses[0]->_classid);376const char* rclass_1_to_upper = toUpper(_rclasses[1]->_classid);377fprintf(fp, "inline const RegMask &%s%s_mask() {"378" return (%s) ?"379" %s%s_mask() :"380" %s%s_mask(); }\n",381prefix, rc_name_to_upper,382_condition_code,383prefix, rclass_0_to_upper,384prefix, rclass_1_to_upper);385if (_stack_or_reg) {386fprintf(fp, "inline const RegMask &%sSTACK_OR_%s_mask() {"387" return (%s) ?"388" %sSTACK_OR_%s_mask() :"389" %sSTACK_OR_%s_mask(); }\n",390prefix, rc_name_to_upper,391_condition_code,392prefix, rclass_0_to_upper,393prefix, rclass_1_to_upper);394}395delete[] rc_name_to_upper;396delete[] rclass_0_to_upper;397delete[] rclass_1_to_upper;398return;399}400401//------------------------------AllocClass-------------------------------------402AllocClass::AllocClass(char *classid) : _classid(classid), _regDef(cmpstr,hashstr, Form::arena) {403}404405// record a register in this class406void AllocClass::addReg(RegDef *regDef) {407assert( regDef != NULL, "Can not add a NULL to an allocation class");408regDef->set_register_num( RegisterForm::_reg_ctr++ );409// Add regDef to this allocation class410_regDefs.addName(regDef->_regname);411_regDef.Insert((void*)regDef->_regname, regDef);412}413414void AllocClass::dump() {415output(stderr);416}417418void AllocClass::output(FILE *fp) { // Write info to output files419fprintf(fp,"AllocClass: %s \n",_classid);420const char *name;421for(_regDefs.reset(); (name = _regDefs.iter()) != NULL;) {422((RegDef*)_regDef[name])->output(fp);423}424fprintf(fp,"--- done with entries for alloc_class %s\n\n",_classid);425}426427//==============================Frame Handling=================================428//------------------------------FrameForm--------------------------------------429FrameForm::FrameForm() {430_frame_pointer = NULL;431_c_frame_pointer = NULL;432_alignment = NULL;433_return_addr = NULL;434_c_return_addr = NULL;435_in_preserve_slots = NULL;436_varargs_C_out_slots_killed = NULL;437_calling_convention = NULL;438_c_calling_convention = NULL;439_return_value = NULL;440_c_return_value = NULL;441_interpreter_frame_pointer_reg = NULL;442}443444FrameForm::~FrameForm() {445}446447void FrameForm::dump() {448output(stderr);449}450451void FrameForm::output(FILE *fp) { // Write info to output files452fprintf(fp,"\nFrame:\n");453}454455//==============================Scheduling=====================================456//------------------------------PipelineForm-----------------------------------457PipelineForm::PipelineForm()458: _reslist ()459, _resdict (cmpstr, hashstr, Form::arena)460, _classdict (cmpstr, hashstr, Form::arena)461, _rescount (0)462, _maxcycleused (0)463, _stages ()464, _stagecnt (0)465, _classlist ()466, _classcnt (0)467, _noplist ()468, _nopcnt (0)469, _variableSizeInstrs (false)470, _branchHasDelaySlot (false)471, _maxInstrsPerBundle (0)472, _maxBundlesPerCycle (1)473, _instrUnitSize (0)474, _bundleUnitSize (0)475, _instrFetchUnitSize (0)476, _instrFetchUnits (0) {477}478PipelineForm::~PipelineForm() {479}480481void PipelineForm::dump() {482output(stderr);483}484485void PipelineForm::output(FILE *fp) { // Write info to output files486const char *res;487const char *stage;488const char *cls;489const char *nop;490int count = 0;491492fprintf(fp,"\nPipeline:");493if (_variableSizeInstrs)494if (_instrUnitSize > 0)495fprintf(fp," variable-sized instructions in %d byte units", _instrUnitSize);496else497fprintf(fp," variable-sized instructions");498else499if (_instrUnitSize > 0)500fprintf(fp," fixed-sized instructions of %d bytes", _instrUnitSize);501else if (_bundleUnitSize > 0)502fprintf(fp," fixed-sized bundles of %d bytes", _bundleUnitSize);503else504fprintf(fp," fixed-sized instructions");505if (_branchHasDelaySlot)506fprintf(fp,", branch has delay slot");507if (_maxInstrsPerBundle > 0)508fprintf(fp,", max of %d instruction%s in parallel",509_maxInstrsPerBundle, _maxInstrsPerBundle > 1 ? "s" : "");510if (_maxBundlesPerCycle > 0)511fprintf(fp,", max of %d bundle%s in parallel",512_maxBundlesPerCycle, _maxBundlesPerCycle > 1 ? "s" : "");513if (_instrFetchUnitSize > 0 && _instrFetchUnits)514fprintf(fp, ", fetch %d x % d bytes per cycle", _instrFetchUnits, _instrFetchUnitSize);515516fprintf(fp,"\nResource:");517for ( _reslist.reset(); (res = _reslist.iter()) != NULL; )518fprintf(fp," %s(0x%08x)", res, _resdict[res]->is_resource()->mask());519fprintf(fp,"\n");520521fprintf(fp,"\nDescription:\n");522for ( _stages.reset(); (stage = _stages.iter()) != NULL; )523fprintf(fp," %s(%d)", stage, count++);524fprintf(fp,"\n");525526fprintf(fp,"\nClasses:\n");527for ( _classlist.reset(); (cls = _classlist.iter()) != NULL; )528_classdict[cls]->is_pipeclass()->output(fp);529530fprintf(fp,"\nNop Instructions:");531for ( _noplist.reset(); (nop = _noplist.iter()) != NULL; )532fprintf(fp, " \"%s\"", nop);533fprintf(fp,"\n");534}535536537//------------------------------ResourceForm-----------------------------------538ResourceForm::ResourceForm(unsigned resmask)539: _resmask(resmask) {540}541ResourceForm::~ResourceForm() {542}543544ResourceForm *ResourceForm::is_resource() const {545return (ResourceForm *)(this);546}547548void ResourceForm::dump() {549output(stderr);550}551552void ResourceForm::output(FILE *fp) { // Write info to output files553fprintf(fp, "resource: 0x%08x;\n", mask());554}555556557//------------------------------PipeClassOperandForm----------------------------------558559void PipeClassOperandForm::dump() {560output(stderr);561}562563void PipeClassOperandForm::output(FILE *fp) { // Write info to output files564fprintf(stderr,"PipeClassOperandForm: %s", _stage);565fflush(stderr);566if (_more_instrs > 0)567fprintf(stderr,"+%d", _more_instrs);568fprintf(stderr," (%s)\n", _iswrite ? "write" : "read");569fflush(stderr);570fprintf(fp,"PipeClassOperandForm: %s", _stage);571if (_more_instrs > 0)572fprintf(fp,"+%d", _more_instrs);573fprintf(fp," (%s)\n", _iswrite ? "write" : "read");574}575576577//------------------------------PipeClassResourceForm----------------------------------578579void PipeClassResourceForm::dump() {580output(stderr);581}582583void PipeClassResourceForm::output(FILE *fp) { // Write info to output files584fprintf(fp,"PipeClassResourceForm: %s at stage %s for %d cycles\n",585_resource, _stage, _cycles);586}587588589//------------------------------PipeClassForm----------------------------------590PipeClassForm::PipeClassForm(const char *id, int num)591: _ident(id)592, _num(num)593, _localNames(cmpstr, hashstr, Form::arena)594, _localUsage(cmpstr, hashstr, Form::arena)595, _has_fixed_latency(0)596, _fixed_latency(0)597, _instruction_count(0)598, _has_multiple_bundles(false)599, _has_branch_delay_slot(false)600, _force_serialization(false)601, _may_have_no_code(false) {602}603604PipeClassForm::~PipeClassForm() {605}606607PipeClassForm *PipeClassForm::is_pipeclass() const {608return (PipeClassForm *)(this);609}610611void PipeClassForm::dump() {612output(stderr);613}614615void PipeClassForm::output(FILE *fp) { // Write info to output files616fprintf(fp,"PipeClassForm: #%03d", _num);617if (_ident)618fprintf(fp," \"%s\":", _ident);619if (_has_fixed_latency)620fprintf(fp," latency %d", _fixed_latency);621if (_force_serialization)622fprintf(fp, ", force serialization");623if (_may_have_no_code)624fprintf(fp, ", may have no code");625fprintf(fp, ", %d instruction%s\n", InstructionCount(), InstructionCount() != 1 ? "s" : "");626}627628629//==============================Peephole Optimization==========================630int Peephole::_peephole_counter = 0;631//------------------------------Peephole---------------------------------------632Peephole::Peephole() : _match(NULL), _constraint(NULL), _replace(NULL), _next(NULL) {633_peephole_number = _peephole_counter++;634}635Peephole::~Peephole() {636}637638// Append a peephole rule with the same root instruction639void Peephole::append_peephole(Peephole *next_peephole) {640if( _next == NULL ) {641_next = next_peephole;642} else {643_next->append_peephole( next_peephole );644}645}646647// Store the components of this peephole rule648void Peephole::add_match(PeepMatch *match) {649assert( _match == NULL, "fatal()" );650_match = match;651}652653void Peephole::append_constraint(PeepConstraint *next_constraint) {654if( _constraint == NULL ) {655_constraint = next_constraint;656} else {657_constraint->append( next_constraint );658}659}660661void Peephole::add_replace(PeepReplace *replace) {662assert( _replace == NULL, "fatal()" );663_replace = replace;664}665666// class Peephole accessor methods are in the declaration.667668669void Peephole::dump() {670output(stderr);671}672673void Peephole::output(FILE *fp) { // Write info to output files674fprintf(fp,"Peephole:\n");675if( _match != NULL ) _match->output(fp);676if( _constraint != NULL ) _constraint->output(fp);677if( _replace != NULL ) _replace->output(fp);678// Output the next entry679if( _next ) _next->output(fp);680}681682//------------------------------PeepMatch--------------------------------------683PeepMatch::PeepMatch(char *rule) : _max_position(0), _rule(rule) {684}685PeepMatch::~PeepMatch() {686}687688689// Insert info into the match-rule690void PeepMatch::add_instruction(int parent, int position, const char *name,691int input) {692if( position > _max_position ) _max_position = position;693694_parent.addName((char*) (intptr_t) parent);695_position.addName((char*) (intptr_t) position);696_instrs.addName(name);697_input.addName((char*) (intptr_t) input);698}699700// Access info about instructions in the peep-match rule701int PeepMatch::max_position() {702return _max_position;703}704705const char *PeepMatch::instruction_name(int position) {706return _instrs.name(position);707}708709// Iterate through all info on matched instructions710void PeepMatch::reset() {711_parent.reset();712_position.reset();713_instrs.reset();714_input.reset();715}716717void PeepMatch::next_instruction(int &parent, int &position, const char* &name, int &input) {718parent = (int) (intptr_t) _parent.iter();719position = (int) (intptr_t) _position.iter();720name = _instrs.iter();721input = (int) (intptr_t) _input.iter();722}723724// 'true' if current position in iteration is a placeholder, not matched.725bool PeepMatch::is_placeholder() {726return _instrs.current_is_signal();727}728729730void PeepMatch::dump() {731output(stderr);732}733734void PeepMatch::output(FILE *fp) { // Write info to output files735fprintf(fp,"PeepMatch:\n");736}737738//------------------------------PeepConstraint---------------------------------739PeepConstraint::PeepConstraint(int left_inst, char* left_op, char* relation,740int right_inst, char* right_op)741: _left_inst(left_inst), _left_op(left_op), _relation(relation),742_right_inst(right_inst), _right_op(right_op), _next(NULL) {}743PeepConstraint::~PeepConstraint() {744}745746// Check if constraints use instruction at position747bool PeepConstraint::constrains_instruction(int position) {748// Check local instruction constraints749if( _left_inst == position ) return true;750if( _right_inst == position ) return true;751752// Check remaining constraints in list753if( _next == NULL ) return false;754else return _next->constrains_instruction(position);755}756757// Add another constraint758void PeepConstraint::append(PeepConstraint *next_constraint) {759if( _next == NULL ) {760_next = next_constraint;761} else {762_next->append( next_constraint );763}764}765766// Access the next constraint in the list767PeepConstraint *PeepConstraint::next() {768return _next;769}770771772void PeepConstraint::dump() {773output(stderr);774}775776void PeepConstraint::output(FILE *fp) { // Write info to output files777fprintf(fp,"PeepConstraint:\n");778}779780//------------------------------PeepReplace------------------------------------781PeepReplace::PeepReplace(char *rule) : _rule(rule) {782}783PeepReplace::~PeepReplace() {784}785786// Add contents of peepreplace787void PeepReplace::add_instruction(char *root) {788_instruction.addName(root);789_operand_inst_num.add_signal();790_operand_op_name.add_signal();791}792void PeepReplace::add_operand( int inst_num, char *inst_operand ) {793_instruction.add_signal();794_operand_inst_num.addName((char*) (intptr_t) inst_num);795_operand_op_name.addName(inst_operand);796}797798// Access contents of peepreplace799void PeepReplace::reset() {800_instruction.reset();801_operand_inst_num.reset();802_operand_op_name.reset();803}804void PeepReplace::next_instruction(const char* &inst){805inst = _instruction.iter();806int inst_num = (int) (intptr_t) _operand_inst_num.iter();807const char* inst_operand = _operand_op_name.iter();808}809void PeepReplace::next_operand(int &inst_num, const char* &inst_operand) {810const char* inst = _instruction.iter();811inst_num = (int) (intptr_t) _operand_inst_num.iter();812inst_operand = _operand_op_name.iter();813}814815816817void PeepReplace::dump() {818output(stderr);819}820821void PeepReplace::output(FILE *fp) { // Write info to output files822fprintf(fp,"PeepReplace:\n");823}824825826