next up previous contents
Next: Application Examples Up: SALTO User Interface Specification Previous: Attributes

Reservation Table Management

 

Resource information accessible to the user covers only resource references: the user cannot change the properties of the hardware resource itself; only resource references made by instructions and represented in reservation tables can be accessed and modified.

The accesses to resources attached to operands can be modified using the operand abstraction. However, to modify resources which do not appear explicitly in the assembly code, it is necessary to manipulate the contents of reservation tables.

In the following, we present the current state of the resource interface, which is undergoing deep restructuring aiming at a more systematic and orthogonal organization.

Resource Descriptions

Resource descriptions in SALTO are maintained as a global resource database, searchable by resource names and ID numbers. Each resource has a unique ID number, a type, a name, and at most two aliases. The global resource database provides translations from resource names to IDs and database entries.

Resource type can be any of UNKNOWN_RTYPE, REGISTER_RTYPE, FUNCT_UNIT_RTYPE, or MEMORY_RTYPE.

Resource descriptions are implemented through the class rdb_res_entry providing the following methods:

char *rdb_res_entry::name(int which = 0)
returns the name of the resource. When non-default values of which (1 and 2) are given, returns respectively the first and the second alias of the resource.
int rdb_res_entry::getType(void)
returns the type of the resource (see above.)
int rdb_res_entry::get_res_limit(void)
returns the replication level of the resource.

To access the contents of the global resource database, it must first be extracted from SALTO's database server by the following statement:

ResourceDataBase &rdb = xxx_server -> GetResT() ;

Once the resource database is extracted, individual resource entries can be searched by name and by resource ID numbers:
ResId_T ResourceDataBase::get_res_id(char *name)
returns the ID of the resource name.
char *ResourceDataBase::get_res_name(ResId_T id)
returns the name of the resource bearing ID number id.
rdb_res_entry *ResourceDataBase::get_res(ResId_T id)
returns the resource entry
matching the id given.
int ResourceDataBase::get_res_limit(char *name)
returns the replication level of resource name.

Resource References

Resource references contain information on resource accesses made during the execution of an instruction. A resource reference represents exactly one resource access: if the same resource is accessed several times during the execution of an instruction, each access will be represented by a separate resource reference object.

Resource references are implemented in class res_ref, further specialized into res_ref_id (basic resource references) and multi_ref (multi-register references). The methods available to the user are:

enum res_ref_type res_ref::get_ref_type(void)
returns the type of the reference.
ResId_T res_ref::get_res_id(void)
returns the ID of the resource accessed by current reference.
bool res_ref::same_res_as(res_ref *otherRef)
returns true if current reference and otherRef correspond to accesses to the same resource.
int res_ref::get_limit(void)
returns the replication level of the resource being accessed.
bool res_ref::norename(void)
returns true if the resource cannot be renamed.
bool multi_ref::same_multires_as(res_ref *otherRef)
returns true if the current reference accesses the same multi-register as otherRef.
res_ref *multi_ref::get_base_res(void)
returns the base register of the current multi-resource (i.e., the resource used as reference point in determining the composition of the multi-register, see section 2.5).
int multi_ref::get_size(void)
returns the number of elements constituting the multi-register being referenced.
int multi_ref::get_index(void)
returns the offset of the first element of a multi-register wrt. its base register (see above.)

Reservation Table Entries

A reservation table entry indicates the nature and the schedule of a resource access: the information it contains specifies what operation is performed on the resource (read, write, use) and when (first and last cycle of the access). Resources which are accessed several times when executing an instruction give raise to as many reservation table entries as there are distinct accesses being made to the resource.

A reservation table entry provides the following functionalities:

res_ref *reserv_entry::get_res(void)
returns the resource reference it describes
void reserv_entry::set_res(res_ref *newRef)
sets the resource reference to newRef.
enum access_mode reserv_entry::get_access_mode(void)
returns the mode of access
made to the resource referenced by the current entry.
void reserv_entry::set_access_mode(enum access_mode newMode)
changes the access mode of the current entry to newMode.
int &reserv_entry::from_cycle(void)
returns a reference to the integer representing the first cycle of the current access.
int &reserv_entry::to_cycle(void)
returns a reference to the integer representing the last cycle of the current access.

Reservation Tables

Reservation tables are use to represent resource accesses within a common time frame, allowing to check for resource access conflicts over that time frame. A reservation table is attached to each assembly instruction, but the user can also set up reservation tables spanning several instructions. Reservation tables are used in instruction scheduling to ensure the feasibility of a given instruction schedule.

Reservation tables are implemented in the class reserv_table1 as lists of reservation table entries and can be manipulated using the following methods of that class:

int get_size(void)
returns the number of entries in the reservation table.
void insert_res(res_ref *ref, enum access_type acc, int fr, int to)
adds an
entry which corresponds to the reference ref made in mode acc between cycles fr and to, inclusive.
void delete_res(int pos)
removes the pos-th entry in the current reservation table.
reserv_entry* get_entry(int pos)
returns the pos-th entry of the current reservation table.
reserv_entry* get_entry(res_ref *ref, enum access_mode acc)
returns the entry of the current reservation table in which the resource referenced by ref is accessed in mode acc.
reserv_entry* get_entry(ResId_T id, enum access_mode access)
returns the entry of the current reservation table in which the resource with ID id is accessed in mode access.

Usage Examples

To illustrate the operation of the current resource interface, let us have a closer look at two short examples: low-level dependence checking, and counting of accesses performed by an instruction.

Flow dependence checking

The following is an excerpt from the implementation of class INST. The method
INST::isRAW(INST *source) is used internally to check if the current instruction may depend on instruction source. For read access made by the current instruction (this), the method searches for a write access to the same resource performed in the instruction supplied as argument.

/*
 * Does instruction -this- have a RAW hazard with -ii- ? 
 * We check if -this- reads a resource written by -ii-.
 */
bool
INST::isRAW(INST *ii, bool ignoreMem)
{
  int      i, j, rRid, rWid;
  int      nOfInput, nOfOutput;
  res_ref  *rread, *rwrite;

  nOfInput = numberOfInput();
  for(i=0; i < nOfInput; i++) {
    rread = getInput(i);	// current insn reads rread
    // if 'rread' is a memory reference and we ignore the mem, let's
    // just skip it 
    if (ignoreMem
	&&
	(rdb . get_res(rread -> get_res_id()) -> getType() == MEMORY_RTYPE))
      continue;
    rRid = rread -> get_res_id();
    nOfOutput = ii -> numberOfOutput();
    for(j=0; j < nOfOutput; j++) { // is it written in instruction 'ii'?
      rwrite = ii -> getOutput(j);
      rWid = rwrite -> get_res_id();
      if (rWid == rRid)
	return true; // if so, there's indeed a RAW hazard between 'ii' and 'this'
    }
  }
  return false;
}

Number of resource accesses

The code below is again taken from the implementation of class INST. The method
INST::numberOfx(...) implements the counting of resource accesses made by an instruction in the access mode specified as argument.

/*
 * Return the number of resources read, written, and used by the
 * instruction.  The same resource will be counted as many times as it is
 * accessed by the instruction.
 */
int
INST::numberOfx(enum access_mode acces)
{
  reserv_table1 *reserv;
  reserv_entry  *entry;
  int           i, k;

  if (!isAsm()) {
    saltoWarn("*** INST::numberOfx(): insn %#lx is not an ASM operation!\n",
	      (unsigned long) this);
    return -1;
  }
  k = 0;
  reserv = ((xAsm *)this) -> get_reser();
  for(i = 0; i < reserv -> get_size(); i++) {
    entry = reserv -> get_entry(i);
    if (entry -> get_access_mode() == acces) k++;
  }
  return k;
}

next up previous contents
Next: Application Examples Up: SALTO User Interface Specification Previous: Attributes

Erven Rohou
Fri Oct 17 09:15:29 MET DST 1997