/* file "libra/libra.h" */

/*
    Copyright (c) 1995-99 The President and Fellows of Harvard University

    All rights reserved.

    This software is provided under the terms described in
    the "machine/copyright.h" include file.
*/

#ifndef LIBRA_LIBRA_H
#define LIBRA_LIBRA_H

#include <machine/copyright.h>

#ifndef SUPPRESS_PRAGMA_INTERFACE
#pragma interface "libra/libra.h"
#endif

#include <machine/machine.h>


/* Entry type for the table of register candidates, which
 * include the hard (machine) registers (HR), plus virtual
 * registers (VR) and local variables (LV) */

class RaCell {
  public:
    RaCell();

    unsigned id;
    unsigned weight;		// weighted occurrence count
    int color;			// -1 or index in "color" map
    Opnd opnd;			// Corresponding HR, VR, or LV operand
    RaCell *temp;		// Point-life VR: holds this value if spilled
};


// Spill counters
extern int spill_load_count;	// number of loads  added by spillage
extern int spill_store_count;	// number of stores added by spillage


/* Scan code of one procedure, updating operands and adding spill code */

class Raga;

typedef OpndFilter::InOrOut InOrOut;
typedef enum { FWD, BWD } scan_edit_direction_t; // FIXME: use bool
typedef void (Raga::*scan_edit_instr_f)(Instr*);
typedef void (Raga::*scan_edit_memory_f)(VarSym*);
typedef bool (Raga::*scan_edit_screen_f)(Opnd);
typedef Opnd (Raga::*scan_edit_reg_cand_f)(Opnd, bool, InstrHandle);
typedef void (Raga::*scan_edit_block_f)(CfgNode*, scan_edit_direction_t);

extern void scan_edit_code(Raga*, Cfg*, scan_edit_instr_f, scan_edit_screen_f,
			   scan_edit_reg_cand_f, scan_edit_reg_cand_f,
			   scan_edit_reg_cand_f, scan_edit_memory_f,
			   scan_edit_direction_t = FWD,
			   scan_edit_block_f = NULL);
extern Opnd
    replace_and_spill(VarSym*, bool, InstrHandle&, Opnd);
extern Instr* load_or_store(bool do_load, Opnd, VarSym*);
extern bool note_spills;

/*
 * Symmetric, irreflexive matrix class
 *
 * Used for interference-graph adjacency matrices
 *
 */
class AdjacencyMatrix {
  public:
    AdjacencyMatrix();
    ~AdjacencyMatrix();
    void clear();
    void insert(int i, int j);
    bool operator()(int i, int j);
  protected:
    NatSetDense *bits;
    int index(int i, int j);
};

extern int find_maximal_regs(int bank, int conv, NatSet *result = NULL);

#endif /* LIBRA_LIBRA_H */
