2010-10-24 Eric Botcazou <ebotcazou@adacore.com>
+ * reg-stack.c (convert_regs_1): Return boolean value, true if the CFG
+ has been modified.
+ (convert_regs_2): Likewise. Adjust calls to convert_regs_1.
+ (convert_regs): Adjust calls to convert_regs_2. Clean up the CFG if
+ it has been modified.
+
+2010-10-24 Eric Botcazou <ebotcazou@adacore.com>
+
* config/sparc/sparc.c (sparc_type_code) <NULLPTR_TYPE>: New case.
2010-10-24 Paul Koning <ni1d@arrl.net>
return (e1->src->index < e2->src->index) ? e1 : e2;
}
-/* Convert stack register references in one block. */
+/* Convert stack register references in one block. Return true if the CFG
+ has been modified in the process. */
-static void
+static bool
convert_regs_1 (basic_block block)
{
struct stack_def regstack;
int reg;
rtx insn, next;
bool control_flow_insn_deleted = false;
+ bool cfg_altered = false;
int debug_insns_with_starting_stack = 0;
any_malformed_asm = false;
place, still, but we don't have enough information at that time. */
if (control_flow_insn_deleted)
- purge_dead_edges (block);
+ cfg_altered |= purge_dead_edges (block);
/* Something failed if the stack lives don't match. If we had malformed
asms, we zapped the instruction itself, but that didn't produce the
|| any_malformed_asm);
bi->stack_out = regstack;
bi->done = true;
+
+ return cfg_altered;
}
-/* Convert registers in all blocks reachable from BLOCK. */
+/* Convert registers in all blocks reachable from BLOCK. Return true if the
+ CFG has been modified in the process. */
-static void
+static bool
convert_regs_2 (basic_block block)
{
basic_block *stack, *sp;
+ bool cfg_altered = false;
/* We process the blocks in a top-down manner, in a way such that one block
is only processed after all its predecessors. The number of predecessors
*sp++ = e->dest;
}
- convert_regs_1 (block);
+ cfg_altered |= convert_regs_1 (block);
}
while (sp != stack);
free (stack);
+
+ return cfg_altered;
}
/* Traverse all basic blocks in a function, converting the register
static void
convert_regs (void)
{
+ bool cfg_altered = false;
int inserted;
basic_block b;
edge e;
/* Process all blocks reachable from all entry points. */
FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR->succs)
- convert_regs_2 (e->dest);
+ cfg_altered |= convert_regs_2 (e->dest);
/* ??? Process all unreachable blocks. Though there's no excuse
for keeping these even when not optimizing. */
block_info bi = BLOCK_INFO (b);
if (! bi->done)
- convert_regs_2 (b);
+ cfg_altered |= convert_regs_2 (b);
}
inserted |= compensate_edges ();
if (inserted)
commit_edge_insertions ();
+ if (cfg_altered)
+ cleanup_cfg (0);
+
if (dump_file)
fputc ('\n', dump_file);
}
--- /dev/null
+-- { dg-do compile }\r
+-- { dg-options "-Os -g" }\r
+\r
+with Opt7_Pkg;\r
+\r
+package body Opt7 is\r
+\r
+ procedure Parse (Str : String;\r
+ Time_Type : out time_t;\r
+ Abs_Time : out Time;\r
+ Delt_Time : out Duration) is\r
+ Year : Year_Number;\r
+ Month : Month_Number;\r
+ Day : Day_Number;\r
+ Minute : Integer := 0;\r
+ Idx : Integer := Str'First;\r
+ Ch : Character := Str (Idx);\r
+ Current_Time : Time;\r
+\r
+ begin\r
+ if Ch = '-' then\r
+ Time_Type := Absolute_Time;\r
+ Current_Time := Clock;\r
+ Day := Ada.Calendar.Day (Current_Time);\r
+ Month := Ada.Calendar.Month (Current_Time);\r
+ Year := Ada.Calendar.Year (Current_Time);\r
+ else\r
+ Time_Type := Delta_Time;\r
+ end if;\r
+ while Ch in '0' .. '9' loop\r
+ Minute := Minute + Character'Pos (Ch);\r
+ Idx := Idx + 1;\r
+ Ch := Str (Idx);\r
+ end loop;\r
+ if Time_Type = Absolute_Time then\r
+ Abs_Time := Time_Of (Year, Month, Day, Day_Duration (1));\r
+ else\r
+ Delt_Time := Duration (Float (Minute));\r
+ end if;\r
+ exception\r
+ when others => Opt7_Pkg.My_Raise_Exception;\r
+ end;\r
+\r
+end Opt7;\r