summaryrefslogtreecommitdiff
path: root/src/arch
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2016-10-28 22:26:53 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2016-10-28 22:26:53 (GMT)
commit8c71b36d401b2473342daddcb9b7eb4b83ba3295 (patch)
tree13515f99f3e01fc2d1701189e500fa69763da7f9 /src/arch
parent2c70e3332b43bdcbe215081b697395d254418e48 (diff)
Optimized access to instruction sources and destinations.
Diffstat (limited to 'src/arch')
-rw-r--r--src/arch/instruction-int.h15
-rw-r--r--src/arch/instruction.c204
-rw-r--r--src/arch/instruction.h37
3 files changed, 100 insertions, 156 deletions
diff --git a/src/arch/instruction-int.h b/src/arch/instruction-int.h
index c393b5f..6c9da03 100644
--- a/src/arch/instruction-int.h
+++ b/src/arch/instruction-int.h
@@ -70,20 +70,13 @@ struct _GArchInstruction
GArchOperand **operands; /* Liste des opérandes */
size_t operands_count; /* Nbre. d'opérandes utilisées */
- GArchInstruction **from; /* Origines des références */
- InstructionLinkType *from_types; /* Type des liens de dest. */
+ instr_link_t *from; /* Origines des références */
size_t from_count; /* Nombre de ces origines */
- GRWLock from_access; /* Verrou de protection */
-#ifndef NDEBUG
- gint hold_from_access; /* Suivi des verrouillages */
-#endif
-
- GArchInstruction **to; /* Eventuelles lignes visées */
- InstructionLinkType *to_types; /* Type des liens de dest. */
+ instr_link_t *to; /* Instructions visées */
size_t to_count; /* Nombre de ces destinations */
- GRWLock to_access; /* Verrou de protection */
+ GRWLock link_access; /* Verrou de protection */
#ifndef NDEBUG
- gint hold_to_access; /* Suivi des verrouillages */
+ gint hold_link_access; /* Suivi des verrouillages */
#endif
//get_instruction_rw_regs_fc get_rw_regs; /* Liste des registres liés */
diff --git a/src/arch/instruction.c b/src/arch/instruction.c
index fa631ac..b57b49d 100644
--- a/src/arch/instruction.c
+++ b/src/arch/instruction.c
@@ -107,11 +107,10 @@ static void g_arch_instruction_init(GArchInstruction *instr)
instr->max_displayed_len = VMPA_NO_PHYSICAL;
- g_rw_lock_init(&instr->from_access);
- g_atomic_int_set(&instr->hold_from_access, 0);
-
- g_rw_lock_init(&instr->to_access);
- g_atomic_int_set(&instr->hold_to_access, 0);
+ g_rw_lock_init(&instr->link_access);
+#ifndef NDEBUG
+ g_atomic_int_set(&instr->hold_link_access, 0);
+#endif
}
@@ -149,8 +148,7 @@ static void g_arch_instruction_dispose(GArchInstruction *instr)
static void g_arch_instruction_finalize(GArchInstruction *instr)
{
- g_rw_lock_clear(&instr->from_access);
- g_rw_lock_clear(&instr->to_access);
+ g_rw_lock_clear(&instr->link_access);
G_OBJECT_CLASS(g_arch_instruction_parent_class)->finalize(G_OBJECT(instr));
@@ -559,6 +557,46 @@ void g_arch_instruction_get_rw_registers(const GArchInstruction *instr, GArchReg
/******************************************************************************
* *
+* Paramètres : instr = instruction à mettre à jour. *
+* write = précise le type d'accès prévu (lecture/écriture). *
+* lock = indique le sens du verrouillage à mener. *
+* *
+* Description : Met à disposition un encadrement des accès aux liens. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_arch_instruction_lock_unlock_links(GArchInstruction *instr, bool write, bool lock)
+{
+#ifndef NDEBUG
+ if (!lock)
+ g_atomic_int_dec_and_test(&instr->hold_link_access);
+#endif
+
+ if (write)
+ {
+ if (lock) g_rw_lock_writer_lock(&instr->link_access);
+ else g_rw_lock_writer_unlock(&instr->link_access);
+ }
+ else
+ {
+ if (lock) g_rw_lock_reader_lock(&instr->link_access);
+ else g_rw_lock_reader_unlock(&instr->link_access);
+ }
+
+#ifndef NDEBUG
+ if (lock)
+ g_atomic_int_inc(&instr->hold_link_access);
+#endif
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : instr = instruction dont les informations sont à consulter. *
* dest = ligne visée par la liaison (côté destination). *
* type = type de lien à construire. *
@@ -575,6 +613,7 @@ void g_arch_instruction_get_rw_registers(const GArchInstruction *instr, GArchReg
void g_arch_instruction_link_with(GArchInstruction *instr, GArchInstruction *dest, InstructionLinkType type)
{
size_t count; /* Raccourci pour la lecture */
+ instr_link_t *new; /* Nouveau lien à définir */
/* Côté destination */
@@ -582,13 +621,12 @@ void g_arch_instruction_link_with(GArchInstruction *instr, GArchInstruction *des
count = ++dest->from_count;
- dest->from = (GArchInstruction **)realloc(dest->from,
- count * sizeof(GArchInstruction *));
- dest->from_types = (InstructionLinkType *)realloc(dest->from_types,
- count * sizeof(InstructionLinkType));
+ dest->from = (instr_link_t *)realloc(dest->from, count * sizeof(instr_link_t));
+
+ new = &dest->from[count - 1];
- dest->from[count - 1] = instr;
- dest->from_types[count - 1] = type;
+ new->linked = instr;
+ new->type = type;
g_arch_instruction_wunlock_src(dest);
@@ -598,13 +636,12 @@ void g_arch_instruction_link_with(GArchInstruction *instr, GArchInstruction *des
count = ++instr->to_count;
- instr->to = (GArchInstruction **)realloc(instr->to,
- count * sizeof(GArchInstruction *));
- instr->to_types = (InstructionLinkType *)realloc(instr->to_types,
- count * sizeof(InstructionLinkType));
+ instr->to = (instr_link_t *)realloc(instr->to, count * sizeof(instr_link_t));
+
+ new = &instr->to[count - 1];
- instr->to[count - 1] = dest;
- instr->to_types[count - 1] = type;
+ new->linked = dest;
+ new->type = type;
g_arch_instruction_wunlock_dest(instr);
@@ -636,7 +673,7 @@ bool g_arch_instruction_change_link(GArchInstruction *instr, GArchInstruction *d
result = false;
- assert(g_atomic_int_get(&instr->hold_to_access) > 0);
+ assert(g_atomic_int_get(&instr->hold_link_access) > 0);
g_arch_instruction_wlock_src(dest);
@@ -645,7 +682,7 @@ bool g_arch_instruction_change_link(GArchInstruction *instr, GArchInstruction *d
count = dest->from_count;
for (i = 0; i < count; i++)
- if (dest->from[i] == instr && dest->from_types[i] == old)
+ if (dest->from[i].linked == instr && dest->from[i].type == old)
break;
if (i == count)
@@ -658,7 +695,7 @@ bool g_arch_instruction_change_link(GArchInstruction *instr, GArchInstruction *d
count = instr->to_count;
for (i = 0; i < count; i++)
- if (instr->to[i] == dest && instr->to_types[i] == old)
+ if (instr->to[i].linked == dest && instr->to[i].type == old)
break;
if (i == count)
@@ -668,9 +705,9 @@ bool g_arch_instruction_change_link(GArchInstruction *instr, GArchInstruction *d
/* Si les deux extrémités sont raccord... */
- dest->from_types[from_idx] = new;
+ dest->from[from_idx].type = new;
- instr->to_types[to_idx] = new;
+ instr->to[to_idx].type = new;
result = true;
@@ -680,49 +717,6 @@ bool g_arch_instruction_change_link(GArchInstruction *instr, GArchInstruction *d
return result;
-
- /* TODO : si les informations complémentaires restent en place, compléter ! */
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : collec = collection à mettre à jour. *
-* write = précise le type d'accès prévu (lecture/écriture). *
-* lock = indique le sens du verrouillage à mener. *
-* *
-* Description : Met à disposition un encadrement des accès aux sources. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-void g_arch_instruction_lock_unlock_sources(GArchInstruction *instr, bool write, bool lock)
-{
-#ifndef NDEBUG
- if (!lock)
- g_atomic_int_dec_and_test(&instr->hold_from_access);
-#endif
-
- if (write)
- {
- if (lock) g_rw_lock_writer_lock(&instr->from_access);
- else g_rw_lock_writer_unlock(&instr->from_access);
- }
- else
- {
- if (lock) g_rw_lock_reader_lock(&instr->from_access);
- else g_rw_lock_reader_unlock(&instr->from_access);
- }
-
-#ifndef NDEBUG
- if (lock)
- g_atomic_int_inc(&instr->hold_from_access);
-#endif
-
}
@@ -740,7 +734,7 @@ void g_arch_instruction_lock_unlock_sources(GArchInstruction *instr, bool write,
bool g_arch_instruction_has_sources(const GArchInstruction *instr)
{
- assert(g_atomic_int_get(&instr->hold_from_access) > 0);
+ assert(g_atomic_int_get(&instr->hold_link_access) > 0);
return (instr->from_count > 0);
@@ -749,9 +743,8 @@ bool g_arch_instruction_has_sources(const GArchInstruction *instr)
/******************************************************************************
* *
-* Paramètres : instr = instruction dont les informations sont à consulter. *
-* srcs = liste des instructions d'origine. [OUT] *
-* types = liste des types de liens présents. [OUT] *
+* Paramètres : instr = instruction dont les informations sont à consulter.*
+* sources = liste des liens aux instructions d'origine. [OUT] *
* *
* Description : Fournit les origines d'une instruction donnée. *
* *
@@ -761,15 +754,12 @@ bool g_arch_instruction_has_sources(const GArchInstruction *instr)
* *
******************************************************************************/
-size_t g_arch_instruction_get_sources(const GArchInstruction *instr, GArchInstruction ***srcs, InstructionLinkType **types)
+size_t g_arch_instruction_get_sources(const GArchInstruction *instr, instr_link_t **sources)
{
- assert(g_atomic_int_get(&instr->hold_from_access) > 0);
-
- if (srcs != NULL)
- *srcs = instr->from;
+ assert(g_atomic_int_get(&instr->hold_link_access) > 0);
- if (types != NULL)
- *types = instr->from_types;
+ if (sources != NULL)
+ *sources = instr->from;
return instr->from_count;
@@ -778,46 +768,6 @@ size_t g_arch_instruction_get_sources(const GArchInstruction *instr, GArchInstru
/******************************************************************************
* *
-* Paramètres : collec = collection à mettre à jour. *
-* write = précise le type d'accès prévu (lecture/écriture). *
-* lock = indique le sens du verrouillage à mener. *
-* *
-* Description : Met à disposition un encadrement des accès aux destinations. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-void g_arch_instruction_lock_unlock_destinations(GArchInstruction *instr, bool write, bool lock)
-{
-#ifndef NDEBUG
- if (!lock)
- g_atomic_int_dec_and_test(&instr->hold_to_access);
-#endif
-
- if (write)
- {
- if (lock) g_rw_lock_writer_lock(&instr->to_access);
- else g_rw_lock_writer_unlock(&instr->to_access);
- }
- else
- {
- if (lock) g_rw_lock_reader_lock(&instr->to_access);
- else g_rw_lock_reader_unlock(&instr->to_access);
- }
-
-#ifndef NDEBUG
- if (lock)
- g_atomic_int_inc(&instr->hold_to_access);
-#endif
-
-}
-
-
-/******************************************************************************
-* *
* Paramètres : instr = instruction dont les informations sont à consulter. *
* *
* Description : Indique si l'instruction a une suite autre que la suivante. *
@@ -830,7 +780,7 @@ void g_arch_instruction_lock_unlock_destinations(GArchInstruction *instr, bool w
bool g_arch_instruction_has_destinations(const GArchInstruction *instr)
{
- assert(g_atomic_int_get(&instr->hold_to_access) > 0);
+ assert(g_atomic_int_get(&instr->hold_link_access) > 0);
return (instr->to_count > 0);
@@ -840,8 +790,7 @@ bool g_arch_instruction_has_destinations(const GArchInstruction *instr)
/******************************************************************************
* *
* Paramètres : instr = instruction dont les informations sont à consulter. *
-* dests = liste des instructions de destination. [OUT] *
-* types = liste des types de liens présents. [OUT] *
+* dests = liste de liens aux instructions de destination. [OUT]*
* *
* Description : Fournit les destinations d'une instruction donnée. *
* *
@@ -851,16 +800,13 @@ bool g_arch_instruction_has_destinations(const GArchInstruction *instr)
* *
******************************************************************************/
-size_t g_arch_instruction_get_destinations(const GArchInstruction *instr, GArchInstruction ***dests, InstructionLinkType **types)
+size_t g_arch_instruction_get_destinations(const GArchInstruction *instr, instr_link_t **dests)
{
- assert(g_atomic_int_get(&instr->hold_to_access) > 0);
+ assert(g_atomic_int_get(&instr->hold_link_access) > 0);
if (dests != NULL)
*dests = instr->to;
- if (types != NULL)
- *types = instr->to_types;
-
return instr->to_count;
}
@@ -886,11 +832,11 @@ GArchInstruction *g_arch_instruction_get_given_destination(const GArchInstructio
result = NULL;
- assert(g_atomic_int_get(&instr->hold_to_access) > 0);
+ assert(g_atomic_int_get(&instr->hold_link_access) > 0);
for (i = 0; i < instr->to_count && result == NULL; i++)
- if (instr->to_types[i] == type)
- result = instr->to[i];
+ if (instr->to[i].type == type)
+ result = instr->to[i].linked;
return result;
diff --git a/src/arch/instruction.h b/src/arch/instruction.h
index 00e64ab..fed88a3 100644
--- a/src/arch/instruction.h
+++ b/src/arch/instruction.h
@@ -174,6 +174,17 @@ typedef enum _InstructionLinkType
} InstructionLinkType;
+/* Déscription d'une liaison entre deux instructions */
+typedef struct _instr_link_t
+{
+ GArchInstruction *linked; /* Autre instruction liée */
+ InstructionLinkType type; /* Type de liaison */
+
+} instr_link_t;
+
+
+/* Met à disposition un encadrement des accès aux liens. */
+void g_arch_instruction_lock_unlock_links(GArchInstruction *, bool, bool);
/* Etablit un lien entre deux instructions. */
void g_arch_instruction_link_with(GArchInstruction *, GArchInstruction *, InstructionLinkType);
@@ -181,35 +192,29 @@ void g_arch_instruction_link_with(GArchInstruction *, GArchInstruction *, Instru
/* Change la nature d'un lien entre deux instructions. */
bool g_arch_instruction_change_link(GArchInstruction *, GArchInstruction *, InstructionLinkType, InstructionLinkType);
-/* Met à disposition un encadrement des accès aux sources. */
-void g_arch_instruction_lock_unlock_sources(GArchInstruction *, bool, bool);
-
-#define g_arch_instruction_wlock_src(ins) g_arch_instruction_lock_unlock_sources(ins, true, true)
-#define g_arch_instruction_wunlock_src(ins) g_arch_instruction_lock_unlock_sources(ins, true, false)
+#define g_arch_instruction_wlock_src(ins) g_arch_instruction_lock_unlock_links(ins, true, true)
+#define g_arch_instruction_wunlock_src(ins) g_arch_instruction_lock_unlock_links(ins, true, false)
-#define g_arch_instruction_rlock_src(ins) g_arch_instruction_lock_unlock_sources(ins, false, true)
-#define g_arch_instruction_runlock_src(ins) g_arch_instruction_lock_unlock_sources(ins, false, false)
+#define g_arch_instruction_rlock_src(ins) g_arch_instruction_lock_unlock_links(ins, false, true)
+#define g_arch_instruction_runlock_src(ins) g_arch_instruction_lock_unlock_links(ins, false, false)
/* Indique si l'instruction a une ou plusieurs origines. */
bool g_arch_instruction_has_sources(const GArchInstruction *);
/* Fournit les origines d'une instruction donnée. */
-size_t g_arch_instruction_get_sources(const GArchInstruction *, GArchInstruction ***, InstructionLinkType **);
-
-/* Met à disposition un encadrement des accès aux destinations. */
-void g_arch_instruction_lock_unlock_destinations(GArchInstruction *, bool, bool);
+size_t g_arch_instruction_get_sources(const GArchInstruction *, instr_link_t **);
-#define g_arch_instruction_wlock_dest(ins) g_arch_instruction_lock_unlock_destinations(ins, true, true)
-#define g_arch_instruction_wunlock_dest(ins) g_arch_instruction_lock_unlock_destinations(ins, true, false)
+#define g_arch_instruction_wlock_dest(ins) g_arch_instruction_lock_unlock_links(ins, true, true)
+#define g_arch_instruction_wunlock_dest(ins) g_arch_instruction_lock_unlock_links(ins, true, false)
-#define g_arch_instruction_rlock_dest(ins) g_arch_instruction_lock_unlock_destinations(ins, false, true)
-#define g_arch_instruction_runlock_dest(ins) g_arch_instruction_lock_unlock_destinations(ins, false, false)
+#define g_arch_instruction_rlock_dest(ins) g_arch_instruction_lock_unlock_links(ins, false, true)
+#define g_arch_instruction_runlock_dest(ins) g_arch_instruction_lock_unlock_links(ins, false, false)
/* Indique si l'instruction a une suite autre que la suivante. */
bool g_arch_instruction_has_destinations(const GArchInstruction *);
/* Fournit les destinations d'une instruction donnée. */
-size_t g_arch_instruction_get_destinations(const GArchInstruction *, GArchInstruction ***, InstructionLinkType **);
+size_t g_arch_instruction_get_destinations(const GArchInstruction *, instr_link_t **);
/* Fournit la destination d'une instruction et d'un type donné. */
GArchInstruction *g_arch_instruction_get_given_destination(const GArchInstruction *, InstructionLinkType);