alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (formsopt.cpp)

This example Java source code file (formsopt.cpp) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

allocclass, form::arena, instructioncount, null, peepconstraint, pipeclassform, regclass, regclass\*, regdef, regdef\*, registerform, registerform\:\:_reg_ctr, resourceform, write

The formsopt.cpp Java example source code

/*
 * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */

// FORMS.CPP - Definitions for ADL Parser Forms Classes
#include "adlc.hpp"

//==============================Register Allocation============================
int RegisterForm::_reg_ctr = 0;

//------------------------------RegisterForm-----------------------------------
// Constructor
RegisterForm::RegisterForm()
  : _regDef(cmpstr,hashstr, Form::arena),
    _regClass(cmpstr,hashstr, Form::arena),
    _allocClass(cmpstr,hashstr, Form::arena) {
}
RegisterForm::~RegisterForm() {
}

// record a new register definition
void RegisterForm::addRegDef(char *name, char *callingConv, char *c_conv,
                             char *idealtype, char *encoding, char* concrete) {
  RegDef *regDef = new RegDef(name, callingConv, c_conv, idealtype, encoding, concrete);
  _rdefs.addName(name);
  _regDef.Insert(name,regDef);
}

// record a new register class
RegClass *RegisterForm::addRegClass(const char *className) {
  RegClass *regClass = new RegClass(className);
  _rclasses.addName(className);
  _regClass.Insert(className,regClass);
  return regClass;
}

// record a new register class
AllocClass *RegisterForm::addAllocClass(char *className) {
  AllocClass *allocClass = new AllocClass(className);
  _aclasses.addName(className);
  _allocClass.Insert(className,allocClass);
  return allocClass;
}

// Called after parsing the Register block.  Record the register class
// for spill-slots/regs.
void RegisterForm::addSpillRegClass() {
  // Stack slots start at the next available even register number.
  _reg_ctr = (_reg_ctr+7) & ~7;
  const char *rc_name   = "stack_slots";
  RegClass   *reg_class = new RegClass(rc_name);
  reg_class->_stack_or_reg = true;
  _rclasses.addName(rc_name);
  _regClass.Insert(rc_name,reg_class);
}


// Provide iteration over all register definitions
// in the order used by the register allocator
void        RegisterForm::reset_RegDefs() {
  _current_ac = NULL;
  _aclasses.reset();
}

RegDef     *RegisterForm::iter_RegDefs() {
  // Check if we need to get the next AllocClass
  if ( _current_ac == NULL ) {
    const char *ac_name = _aclasses.iter();
    if( ac_name == NULL )   return NULL;   // No more allocation classes
    _current_ac = (AllocClass*)_allocClass[ac_name];
    _current_ac->_regDefs.reset();
    assert( _current_ac != NULL, "Name must match an allocation class");
  }

  const char *rd_name = _current_ac->_regDefs.iter();
  if( rd_name == NULL ) {
    // At end of this allocation class, check the next
    _current_ac = NULL;
    return iter_RegDefs();
  }
  RegDef *reg_def = (RegDef*)_current_ac->_regDef[rd_name];
  assert( reg_def != NULL, "Name must match a register definition");
  return reg_def;
}

// return the register definition with name 'regName'
RegDef *RegisterForm::getRegDef(const char *regName) {
  RegDef *regDef = (RegDef*)_regDef[regName];
  return  regDef;
}

// return the register class with name 'className'
RegClass *RegisterForm::getRegClass(const char *className) {
  RegClass *regClass = (RegClass*)_regClass[className];
  return    regClass;
}


// Check that register classes are compatible with chunks
bool   RegisterForm::verify() {
  bool valid = true;

  // Verify Register Classes
  // check that each register class contains registers from one chunk
  const char *rc_name = NULL;
  _rclasses.reset();
  while ( (rc_name = _rclasses.iter()) != NULL ) {
    // Check the chunk value for all registers in this class
    RegClass *reg_class = getRegClass(rc_name);
    assert( reg_class != NULL, "InternalError() no matching register class");
  } // end of RegClasses

  // Verify that every register has been placed into an allocation class
  RegDef *reg_def = NULL;
  reset_RegDefs();
  uint  num_register_zero = 0;
  while ( (reg_def = iter_RegDefs()) != NULL ) {
    if( reg_def->register_num() == 0 )  ++num_register_zero;
  }
  if( num_register_zero > 1 ) {
    fprintf(stderr,
            "ERROR: More than one register has been assigned register-number 0.\n"
            "Probably because a register has not been entered into an allocation class.\n");
  }

  return  valid;
}

// Compute RegMask size
int RegisterForm::RegMask_Size() {
  // Need at least this many words
  int words_for_regs = (_reg_ctr + 31)>>5;
  // The array of Register Mask bits should be large enough to cover
  // all the machine registers and all parameters that need to be passed
  // on the stack (stack registers) up to some interesting limit.  Methods
  // that need more parameters will NOT be compiled.  On Intel, the limit
  // is something like 90+ parameters.
  // Add a few (3 words == 96 bits) for incoming & outgoing arguments to calls.
  // Round up to the next doubleword size.
  return (words_for_regs + 3 + 1) & ~1;
}

void RegisterForm::dump() {                  // Debug printer
  output(stderr);
}

void RegisterForm::output(FILE *fp) {          // Write info to output files
  const char *name;
  fprintf(fp,"\n");
  fprintf(fp,"-------------------- Dump RegisterForm --------------------\n");
  for(_rdefs.reset(); (name = _rdefs.iter()) != NULL;) {
    ((RegDef*)_regDef[name])->output(fp);
  }
  fprintf(fp,"\n");
  for (_rclasses.reset(); (name = _rclasses.iter()) != NULL;) {
    ((RegClass*)_regClass[name])->output(fp);
  }
  fprintf(fp,"\n");
  for (_aclasses.reset(); (name = _aclasses.iter()) != NULL;) {
    ((AllocClass*)_allocClass[name])->output(fp);
  }
  fprintf(fp,"-------------------- end  RegisterForm --------------------\n");
}

//------------------------------RegDef-----------------------------------------
// Constructor
RegDef::RegDef(char *regname, char *callconv, char *c_conv, char * idealtype, char * encode, char * concrete)
  : _regname(regname), _callconv(callconv), _c_conv(c_conv),
    _idealtype(idealtype),
    _register_encode(encode),
    _concrete(concrete),
    _register_num(0) {

  // Chunk and register mask are determined by the register number
  // _register_num is set when registers are added to an allocation class
}
RegDef::~RegDef() {                      // Destructor
}

void RegDef::set_register_num(uint32 register_num) {
  _register_num      = register_num;
}

// Bit pattern used for generating machine code
const char* RegDef::register_encode() const {
  return _register_encode;
}

// Register number used in machine-independent code
uint32 RegDef::register_num()    const {
  return _register_num;
}

void RegDef::dump() {
  output(stderr);
}

void RegDef::output(FILE *fp) {         // Write info to output files
  fprintf(fp,"RegDef: %s (%s) encode as %s  using number %d\n",
          _regname, (_callconv?_callconv:""), _register_encode, _register_num);
  fprintf(fp,"\n");
}


//------------------------------RegClass---------------------------------------
// Construct a register class into which registers will be inserted
RegClass::RegClass(const char *classid) : _stack_or_reg(false), _classid(classid), _regDef(cmpstr,hashstr, Form::arena),
                                          _user_defined(NULL)
{
}

// record a register in this class
void RegClass::addReg(RegDef *regDef) {
  _regDefs.addName(regDef->_regname);
  _regDef.Insert((void*)regDef->_regname, regDef);
}

// Number of registers in class
uint RegClass::size() const {
  return _regDef.Size();
}

const RegDef *RegClass::get_RegDef(const char *rd_name) const {
  return  (const RegDef*)_regDef[rd_name];
}

void RegClass::reset() {
  _regDefs.reset();
}

const char *RegClass::rd_name_iter() {
  return _regDefs.iter();
}

RegDef *RegClass::RegDef_iter() {
  const char *rd_name  = rd_name_iter();
  RegDef     *reg_def  = rd_name ? (RegDef*)_regDef[rd_name] : NULL;
  return      reg_def;
}

const RegDef* RegClass::find_first_elem() {
  const RegDef* first = NULL;
  const RegDef* def = NULL;

  reset();
  while ((def = RegDef_iter()) != NULL) {
    if (first == NULL || def->register_num() < first->register_num()) {
      first = def;
    }
  }

  assert(first != NULL, "empty mask?");
  return first;;
}

// Collect all the registers in this register-word.  One bit per register.
int RegClass::regs_in_word( int wordnum, bool stack_also ) {
  int         word = 0;
  const char *name;
  for(_regDefs.reset(); (name = _regDefs.iter()) != NULL;) {
    int rnum = ((RegDef*)_regDef[name])->register_num();
    if( (rnum >> 5) == wordnum )
      word |= (1 << (rnum & 31));
  }
  if( stack_also ) {
    // Now also collect stack bits
    for( int i = 0; i < 32; i++ )
      if( wordnum*32+i >= RegisterForm::_reg_ctr )
        word |= (1 << i);
  }

  return word;
}

void RegClass::dump() {
  output(stderr);
}

void RegClass::output(FILE *fp) {           // Write info to output files
  fprintf(fp,"RegClass: %s\n",_classid);
  const char *name;
  for(_regDefs.reset(); (name = _regDefs.iter()) != NULL;) {
    ((RegDef*)_regDef[name])->output(fp);
  }
  fprintf(fp,"--- done with entries for reg_class %s\n\n",_classid);
}


//------------------------------AllocClass-------------------------------------
AllocClass::AllocClass(char *classid) : _classid(classid), _regDef(cmpstr,hashstr, Form::arena) {
}

// record a register in this class
void AllocClass::addReg(RegDef *regDef) {
  assert( regDef != NULL, "Can not add a NULL to an allocation class");
  regDef->set_register_num( RegisterForm::_reg_ctr++ );
  // Add regDef to this allocation class
  _regDefs.addName(regDef->_regname);
  _regDef.Insert((void*)regDef->_regname, regDef);
}

void AllocClass::dump() {
  output(stderr);
}

void AllocClass::output(FILE *fp) {       // Write info to output files
  fprintf(fp,"AllocClass: %s \n",_classid);
  const char *name;
  for(_regDefs.reset(); (name = _regDefs.iter()) != NULL;) {
    ((RegDef*)_regDef[name])->output(fp);
  }
  fprintf(fp,"--- done with entries for alloc_class %s\n\n",_classid);
}

//==============================Frame Handling=================================
//------------------------------FrameForm--------------------------------------
FrameForm::FrameForm() {
  _frame_pointer = NULL;
  _c_frame_pointer = NULL;
  _alignment = NULL;
  _return_addr = NULL;
  _c_return_addr = NULL;
  _in_preserve_slots = NULL;
  _varargs_C_out_slots_killed = NULL;
  _calling_convention = NULL;
  _c_calling_convention = NULL;
  _return_value = NULL;
  _c_return_value = NULL;
  _interpreter_frame_pointer_reg = NULL;
}

FrameForm::~FrameForm() {
}

void FrameForm::dump() {
  output(stderr);
}

void FrameForm::output(FILE *fp) {           // Write info to output files
  fprintf(fp,"\nFrame:\n");
}

//==============================Scheduling=====================================
//------------------------------PipelineForm-----------------------------------
PipelineForm::PipelineForm()
  :  _reslist               ()
  ,  _resdict               (cmpstr, hashstr, Form::arena)
  ,  _classdict             (cmpstr, hashstr, Form::arena)
  ,  _rescount              (0)
  ,  _maxcycleused          (0)
  ,  _stages                ()
  ,  _stagecnt              (0)
  ,  _classlist             ()
  ,  _classcnt              (0)
  ,  _noplist               ()
  ,  _nopcnt                (0)
  ,  _variableSizeInstrs    (false)
  ,  _branchHasDelaySlot    (false)
  ,  _maxInstrsPerBundle    (0)
  ,  _maxBundlesPerCycle    (1)
  ,  _instrUnitSize         (0)
  ,  _bundleUnitSize        (0)
  ,  _instrFetchUnitSize    (0)
  ,  _instrFetchUnits       (0) {
}
PipelineForm::~PipelineForm() {
}

void PipelineForm::dump() {
  output(stderr);
}

void PipelineForm::output(FILE *fp) {           // Write info to output files
  const char *res;
  const char *stage;
  const char *cls;
  const char *nop;
  int count = 0;

  fprintf(fp,"\nPipeline:");
  if (_variableSizeInstrs)
    if (_instrUnitSize > 0)
      fprintf(fp," variable-sized instructions in %d byte units", _instrUnitSize);
    else
      fprintf(fp," variable-sized instructions");
  else
    if (_instrUnitSize > 0)
      fprintf(fp," fixed-sized instructions of %d bytes", _instrUnitSize);
    else if (_bundleUnitSize > 0)
      fprintf(fp," fixed-sized bundles of %d bytes", _bundleUnitSize);
    else
      fprintf(fp," fixed-sized instructions");
  if (_branchHasDelaySlot)
    fprintf(fp,", branch has delay slot");
  if (_maxInstrsPerBundle > 0)
    fprintf(fp,", max of %d instruction%s in parallel",
      _maxInstrsPerBundle, _maxInstrsPerBundle > 1 ? "s" : "");
  if (_maxBundlesPerCycle > 0)
    fprintf(fp,", max of %d bundle%s in parallel",
      _maxBundlesPerCycle, _maxBundlesPerCycle > 1 ? "s" : "");
  if (_instrFetchUnitSize > 0 && _instrFetchUnits)
    fprintf(fp, ", fetch %d x % d bytes per cycle", _instrFetchUnits, _instrFetchUnitSize);

  fprintf(fp,"\nResource:");
  for ( _reslist.reset(); (res = _reslist.iter()) != NULL; )
    fprintf(fp," %s(0x%08x)", res, _resdict[res]->is_resource()->mask());
  fprintf(fp,"\n");

  fprintf(fp,"\nDescription:\n");
  for ( _stages.reset(); (stage = _stages.iter()) != NULL; )
    fprintf(fp," %s(%d)", stage, count++);
  fprintf(fp,"\n");

  fprintf(fp,"\nClasses:\n");
  for ( _classlist.reset(); (cls = _classlist.iter()) != NULL; )
    _classdict[cls]->is_pipeclass()->output(fp);

  fprintf(fp,"\nNop Instructions:");
  for ( _noplist.reset(); (nop = _noplist.iter()) != NULL; )
    fprintf(fp, " \"%s\"", nop);
  fprintf(fp,"\n");
}


//------------------------------ResourceForm-----------------------------------
ResourceForm::ResourceForm(unsigned resmask)
: _resmask(resmask) {
}
ResourceForm::~ResourceForm() {
}

ResourceForm  *ResourceForm::is_resource() const {
  return (ResourceForm *)(this);
}

void ResourceForm::dump() {
  output(stderr);
}

void ResourceForm::output(FILE *fp) {          // Write info to output files
  fprintf(fp, "resource: 0x%08x;\n", mask());
}


//------------------------------PipeClassOperandForm----------------------------------

void PipeClassOperandForm::dump() {
  output(stderr);
}

void PipeClassOperandForm::output(FILE *fp) {         // Write info to output files
  fprintf(stderr,"PipeClassOperandForm: %s", _stage);
  fflush(stderr);
  if (_more_instrs > 0)
    fprintf(stderr,"+%d", _more_instrs);
  fprintf(stderr," (%s)\n", _iswrite ? "write" : "read");
  fflush(stderr);
  fprintf(fp,"PipeClassOperandForm: %s", _stage);
  if (_more_instrs > 0)
    fprintf(fp,"+%d", _more_instrs);
  fprintf(fp," (%s)\n", _iswrite ? "write" : "read");
}


//------------------------------PipeClassResourceForm----------------------------------

void PipeClassResourceForm::dump() {
  output(stderr);
}

void PipeClassResourceForm::output(FILE *fp) {         // Write info to output files
  fprintf(fp,"PipeClassResourceForm: %s at stage %s for %d cycles\n",
     _resource, _stage, _cycles);
}


//------------------------------PipeClassForm----------------------------------
PipeClassForm::PipeClassForm(const char *id, int num)
  : _ident(id)
  , _num(num)
  , _localNames(cmpstr, hashstr, Form::arena)
  , _localUsage(cmpstr, hashstr, Form::arena)
  , _has_fixed_latency(0)
  , _fixed_latency(0)
  , _instruction_count(0)
  , _has_multiple_bundles(false)
  , _has_branch_delay_slot(false)
  , _force_serialization(false)
  , _may_have_no_code(false) {
}

PipeClassForm::~PipeClassForm() {
}

PipeClassForm  *PipeClassForm::is_pipeclass() const {
  return (PipeClassForm *)(this);
}

void PipeClassForm::dump() {
  output(stderr);
}

void PipeClassForm::output(FILE *fp) {         // Write info to output files
  fprintf(fp,"PipeClassForm: #%03d", _num);
  if (_ident)
     fprintf(fp," \"%s\":", _ident);
  if (_has_fixed_latency)
     fprintf(fp," latency %d", _fixed_latency);
  if (_force_serialization)
     fprintf(fp, ", force serialization");
  if (_may_have_no_code)
     fprintf(fp, ", may have no code");
  fprintf(fp, ", %d instruction%s\n", InstructionCount(), InstructionCount() != 1 ? "s" : "");
}


//==============================Peephole Optimization==========================
int Peephole::_peephole_counter = 0;
//------------------------------Peephole---------------------------------------
Peephole::Peephole() : _match(NULL), _constraint(NULL), _replace(NULL), _next(NULL) {
  _peephole_number = _peephole_counter++;
}
Peephole::~Peephole() {
}

// Append a peephole rule with the same root instruction
void Peephole::append_peephole(Peephole *next_peephole) {
  if( _next == NULL ) {
    _next = next_peephole;
  } else {
    _next->append_peephole( next_peephole );
  }
}

// Store the components of this peephole rule
void Peephole::add_match(PeepMatch *match) {
  assert( _match == NULL, "fatal()" );
  _match = match;
}

void Peephole::append_constraint(PeepConstraint *next_constraint) {
  if( _constraint == NULL ) {
    _constraint = next_constraint;
  } else {
    _constraint->append( next_constraint );
  }
}

void Peephole::add_replace(PeepReplace *replace) {
  assert( _replace == NULL, "fatal()" );
  _replace = replace;
}

// class Peephole accessor methods are in the declaration.


void Peephole::dump() {
  output(stderr);
}

void Peephole::output(FILE *fp) {         // Write info to output files
  fprintf(fp,"Peephole:\n");
  if( _match != NULL )       _match->output(fp);
  if( _constraint != NULL )  _constraint->output(fp);
  if( _replace != NULL )     _replace->output(fp);
  // Output the next entry
  if( _next ) _next->output(fp);
}

//------------------------------PeepMatch--------------------------------------
PeepMatch::PeepMatch(char *rule) : _max_position(0), _rule(rule) {
}
PeepMatch::~PeepMatch() {
}


// Insert info into the match-rule
void  PeepMatch::add_instruction(int parent, int position, const char *name,
                                 int input) {
  if( position > _max_position ) _max_position = position;

  _parent.addName((char*) (intptr_t) parent);
  _position.addName((char*) (intptr_t) position);
  _instrs.addName(name);
  _input.addName((char*) (intptr_t) input);
}

// Access info about instructions in the peep-match rule
int   PeepMatch::max_position() {
  return _max_position;
}

const char *PeepMatch::instruction_name(int position) {
  return _instrs.name(position);
}

// Iterate through all info on matched instructions
void  PeepMatch::reset() {
  _parent.reset();
  _position.reset();
  _instrs.reset();
  _input.reset();
}

void  PeepMatch::next_instruction(int &parent, int &position, const char* &name, int &input) {
  parent   = (int) (intptr_t) _parent.iter();
  position = (int) (intptr_t) _position.iter();
  name     = _instrs.iter();
  input    = (int) (intptr_t) _input.iter();
}

// 'true' if current position in iteration is a placeholder, not matched.
bool  PeepMatch::is_placeholder() {
  return _instrs.current_is_signal();
}


void PeepMatch::dump() {
  output(stderr);
}

void PeepMatch::output(FILE *fp) {        // Write info to output files
  fprintf(fp,"PeepMatch:\n");
}

//------------------------------PeepConstraint---------------------------------
PeepConstraint::PeepConstraint(int left_inst,  char* left_op, char* relation,
                               int right_inst, char* right_op)
  : _left_inst(left_inst), _left_op(left_op), _relation(relation),
    _right_inst(right_inst), _right_op(right_op), _next(NULL) {}
PeepConstraint::~PeepConstraint() {
}

// Check if constraints use instruction at position
bool PeepConstraint::constrains_instruction(int position) {
  // Check local instruction constraints
  if( _left_inst  == position ) return true;
  if( _right_inst == position ) return true;

  // Check remaining constraints in list
  if( _next == NULL )  return false;
  else                 return _next->constrains_instruction(position);
}

// Add another constraint
void PeepConstraint::append(PeepConstraint *next_constraint) {
  if( _next == NULL ) {
    _next = next_constraint;
  } else {
    _next->append( next_constraint );
  }
}

// Access the next constraint in the list
PeepConstraint *PeepConstraint::next() {
  return _next;
}


void PeepConstraint::dump() {
  output(stderr);
}

void PeepConstraint::output(FILE *fp) {   // Write info to output files
  fprintf(fp,"PeepConstraint:\n");
}

//------------------------------PeepReplace------------------------------------
PeepReplace::PeepReplace(char *rule) : _rule(rule) {
}
PeepReplace::~PeepReplace() {
}

// Add contents of peepreplace
void  PeepReplace::add_instruction(char *root) {
  _instruction.addName(root);
  _operand_inst_num.add_signal();
  _operand_op_name.add_signal();
}
void  PeepReplace::add_operand( int inst_num, char *inst_operand ) {
  _instruction.add_signal();
  _operand_inst_num.addName((char*) (intptr_t) inst_num);
  _operand_op_name.addName(inst_operand);
}

// Access contents of peepreplace
void  PeepReplace::reset() {
  _instruction.reset();
  _operand_inst_num.reset();
  _operand_op_name.reset();
}
void  PeepReplace::next_instruction(const char* &inst){
  inst                     = _instruction.iter();
  int         inst_num     = (int) (intptr_t) _operand_inst_num.iter();
  const char* inst_operand = _operand_op_name.iter();
}
void  PeepReplace::next_operand(int &inst_num, const char* &inst_operand) {
  const char* inst = _instruction.iter();
  inst_num         = (int) (intptr_t) _operand_inst_num.iter();
  inst_operand     = _operand_op_name.iter();
}



void PeepReplace::dump() {
  output(stderr);
}

void PeepReplace::output(FILE *fp) {      // Write info to output files
  fprintf(fp,"PeepReplace:\n");
}

Other Java examples (source code examples)

Here is a short list of links related to this Java formsopt.cpp source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.