+#include "irprog_t.h"
+#include "irgraph_t.h"
+#include "pseudo_irg.h"
+#include "array.h"
+#include "error.h"
+#include "obst.h"
+#include "irop_t.h"
+#include "irmemory.h"
+
+/** The initial name of the irp program. */
+#define INITAL_PROG_NAME "no_name_set"
+
+/* A variable from where everything in the ir can be accessed. */
+ir_prog *irp;
+ir_prog *get_irp(void) { return irp; }
+
+/**
+ * Create a new incomplete ir_prog.
+ */
+static ir_prog *new_incomplete_ir_prog(void) {
+ ir_prog *res;
+
+ res = xmalloc(sizeof(*res));
+ memset(res, 0, sizeof(*res));
+
+ res->kind = k_ir_prog;
+ res->graphs = NEW_ARR_F(ir_graph *, 0);
+ res->pseudo_graphs = NEW_ARR_F(ir_graph *, 0);
+ res->types = NEW_ARR_F(ir_type *, 0);
+ res->modes = NEW_ARR_F(ir_mode *, 0);
+ res->opcodes = NEW_ARR_F(ir_op *, 0);
+ res->global_asms = NEW_ARR_F(ident *, 0);
+ res->last_region_nr = 0;
+ res->last_label_nr = 1; /* 0 is reserved as non-label */
+ res->max_irg_idx = 0;
+
+#ifdef DEBUG_libfirm
+ res->max_node_nr = 0;
+#endif
+
+ return res;
+}
+
+/** Completes an incomplete irprog. */
+static ir_prog *complete_ir_prog(ir_prog *irp) {
+ int i;
+#define IDENT(s) new_id_from_chars(s, sizeof(s)-1)
+
+ irp->name = IDENT(INITAL_PROG_NAME);
+
+ irp->segment_types[IR_SEGMENT_GLOBAL] = new_type_class(IDENT("GlobalType"));
+ irp->segment_types[IR_SEGMENT_THREAD_LOCAL]
+ = new_type_struct(IDENT("ThreadLocal"));
+ irp->segment_types[IR_SEGMENT_CONSTRUCTORS]
+ = new_type_struct(IDENT("Constructors"));
+ irp->segment_types[IR_SEGMENT_DESTRUCTORS]
+ = new_type_struct(IDENT("Destructors"));
+ /* Remove these types from type list. Must be treated differently than
+ other types. */
+ for (i = 0; i < IR_SEGMENT_COUNT; ++i) {
+ remove_irp_type(irp->segment_types[i]);
+ }
+
+ /* Set these flags for debugging. */
+ irp->segment_types[IR_SEGMENT_GLOBAL]->flags |= tf_global_type;
+ irp->segment_types[IR_SEGMENT_THREAD_LOCAL]->flags |= tf_tls_type;
+
+ /* The global type is a class, but we cannot derive from it, so set
+ the final property to assist optimizations that checks for it. */
+ set_class_final(irp->segment_types[IR_SEGMENT_GLOBAL], 1);
+
+ irp->const_code_irg = new_const_code_irg();
+
+ irp->phase_state = phase_building;
+ irp->outs_state = outs_none;
+ irp->ip_outedges = NULL;
+ irp->trouts_state = outs_none;
+ irp->class_cast_state = ir_class_casts_transitive;
+ irp->globals_adr_taken_state = ir_address_taken_not_computed;
+
+ return irp;
+#undef IDENT
+}
+
+/* initializes ir_prog. Constructs only the basic lists. */
+void init_irprog_1(void) {
+ irp = new_incomplete_ir_prog();
+}
+
+/* Completes ir_prog. */
+void init_irprog_2(void) {
+ complete_ir_prog(irp);
+}
+
+/* Create a new ir prog. Automatically called by init_firm through
+ init_irprog. */
+ir_prog *new_ir_prog(void) {
+ return complete_ir_prog(new_incomplete_ir_prog());