示例#1
0
    def optimise(self):
        """
        Optimise the IR.

        Procedure:
         1. split in frames
         2. convert frames to graphs
         3. optimise graphs
         4. convert graphs to (flat) frames
         5. concatenate frames to get optimised program.

        Store result in flat.
        
        """


        # top loop
        
        flat_orig = None
        top_loop_counter = 0
        while True:
            if flat_orig == self.flat:
                self.logger.info('optimisation is stable')
                break
            if top_loop_counter == 10000:
                self.logger.warning('top loop limit reached (10000 iterations)')
                break
            flat_orig = self.flat[:]
            top_loop_counter += 1
            self.logger.info('top pass %s' % str(top_loop_counter))           

            # a.
            if 'a' in self.enabled_optimisations:
                self.logger.info('optimising global control flow graph')
            
                cfg = CFG(self.flat)
                #if self.verbosity > 2:
                #    cfg.cfg_to_diagram("allinstr_graph_before.png")    
        
                optimise_tree.optimise(cfg)
                #if self.verbosity > 2:
                #    cfg.cfg_to_diagram("allinstr_graph_after.png")      
                self.flat = cfg.cfg_to_flat()
              
            # b. jump optimisations 
            if 'b' in self.enabled_optimisations:
                self.logger.info('optimising flat (jumps and branches)')
                self.flat = flat_opt.optimise(self.flat)
            
            self.flat = parse_instr.parse(self.flat)
            self.logger.info('splitting flat in frames')
            frames = split_frames(self.flat)
            self.logger.info('creating graph for each frame')
            graphs = [CFG(frame) for frame in frames]  
            
            
            self.logger.info('optimising blocks')    

            for graphnr, graph in enumerate(graphs):
                self.logger.info('graph %d of %d' % (graphnr + 1, len(graphs)))

                #Dataflow(graph)
                if 'f' in self.enabled_optimisations:
                    l = Liveness(graph,self.verbosity)
                    self.logger.info('Performing liveness optimalisation on graph')
                    change = True
                    while change:
                        l.analyse()
                        change = l.optimise()   
                            
                for blocknr, block in enumerate(graph.blocks):
                
                    self.logger.debug('block %d of %d' % (blocknr + 1, len(graph.blocks)))
                   
                    cf_opt = b_opt.ConstantFold(block)
                    cp_opt = b_opt.CopyPropagation(block)
                    dc_opt = b_opt.DeadCode(block)

                    done = False
                    subopt_changes = False
                    i = 0

                    while (not done):
                        done = True
                        i += 1
                        self.logger.debug('\t pass '+str(i))
                   
                        # c. constant folding
                        if 'c' in self.enabled_optimisations:
                            subopt_changes = cf_opt.optimise()
                            if subopt_changes: self.stats['cf'] += cf_opt.stats['cf']
                            done = done & (not subopt_changes)

                        # d. copy propagation
                        if 'd' in self.enabled_optimisations:
                            subopt_changes = cp_opt.optimise()
                            if subopt_changes:self.stats['cp'] += cp_opt.stats['cp']
                            done = done & (not subopt_changes)
                        
                        # e. dead code removal
                        if 'e' in self.enabled_optimisations:
                            subopt_changes = dc_opt.optimise()
                            if subopt_changes:self.stats['dc'] += dc_opt.stats['dc']
                            done = done & (not subopt_changes)

            self.logger.info('basic-block peephole optimisations done:')
            self.logger.info('\t constant folds: %d' % (self.stats['cf']))
            self.logger.info('\t copy propagations: %d' % (self.stats['cp']))
            self.logger.info('\t dead code removes: %d' % (self.stats['dc']))

            self.logger.info('joining graphs to frames')
            frames = [graph.cfg_to_flat() for graph in graphs]
            self.logger.info('joining frames to flat')
            self.flat = sum(frames, [])
示例#2
0
    def optimise(self):
        """
        Optimise the IR.

        Procedure:
         1. split in frames
         2. convert frames to graphs
         3. optimise graphs
         4. convert graphs to (flat) frames
         5. concatenate frames to get optimised program.

        Store result in flat.
        
        """

        self.logger.info('optimising global control flow graph')
        
        cfg = CFG(self.flat)
        if self.verbosity > 2:
            cfg.cfg_to_diagram("allinstr_graph_before.png")    
        optimise_tree.optimise(cfg)
        if self.verbosity > 2:
            cfg.cfg_to_diagram("allinstr_graph_after.png")      
        self.flat = cfg.cfg_to_flat()
        
        self.logger.info('optimising flat (jumps and branches)')
        self.flat = flat_opt.optimise(self.flat)
        
        
         


        self.logger.info('splitting flat in frames')
        frames = split_frames(self.flat)
        self.logger.info('creating graph for each frame')
        graphs = [CFG(frame) for frame in frames]  
        
        self.logger.info('optimising blocks')    

        for graphnr, graph in enumerate(graphs):
            self.logger.info('graph %d of %d' % (graphnr + 1, len(graphs)))

            Dataflow(graph)
            l = Liveness(graph,self.verbosity)

            #self.logger.info('Performing liveness optimalisation on graph')
            #change = True
            #while change:
            #    l.analyse()
            #    change = l.optimise()   
                        
            for blocknr, block in enumerate(graph.blocks):
            
                self.logger.debug('block %d of %d' % (blocknr + 1, len(graph.blocks)))
               
                cf_opt = b_opt.ConstantFold(block)
                cp_opt = b_opt.CopyPropagation(block)
                dc_opt = b_opt.DeadCode(block)

                done = False
                subopt_changes = False
                i = 0

                while (not done):
                    done = True
                    i += 1
                    self.logger.debug('pass '+str(i))

                    subopt_changes = cf_opt.optimise()
                    if subopt_changes:self.stats['cf'] += cf_opt.stats['cf']
                    done = done & (not subopt_changes)

                    subopt_changes = cp_opt.optimise()
                    if subopt_changes:self.stats['cp'] += cp_opt.stats['cp']
                    done = done & (not subopt_changes)
                    
                    subopt_changes = dc_opt.optimise()
                    if subopt_changes:self.stats['dc'] += dc_opt.stats['dc']
                    done = done & (not subopt_changes)

        self.logger.info('basic-block peephole optimisations done:')
        self.logger.info('\t\tconstant folds: %d' % (self.stats['cf']))
        self.logger.info('\t\tcopy propagations: %d' % (self.stats['cp']))
        self.logger.info('\t\tdead code removes: %d' % (self.stats['dc']))
        self.logger.info('joining graphs to frames')
        frames = [graph.cfg_to_flat() for graph in graphs]
        self.logger.info('joining frames to flat')
        self.flat = sum(frames, [])