]> git.saurik.com Git - apple/javascriptcore.git/blame - offlineasm/opt.rb
JavaScriptCore-1097.13.tar.gz
[apple/javascriptcore.git] / offlineasm / opt.rb
CommitLineData
6fe7ccc8
A
1# Copyright (C) 2011 Apple Inc. All rights reserved.
2#
3# Redistribution and use in source and binary forms, with or without
4# modification, are permitted provided that the following conditions
5# are met:
6# 1. Redistributions of source code must retain the above copyright
7# notice, this list of conditions and the following disclaimer.
8# 2. Redistributions in binary form must reproduce the above copyright
9# notice, this list of conditions and the following disclaimer in the
10# documentation and/or other materials provided with the distribution.
11#
12# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
13# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
14# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
15# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
16# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
17# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
18# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
19# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
20# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
21# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
22# THE POSSIBILITY OF SUCH DAMAGE.
23
24require "ast"
25
26#
27# "Optimization" passes. These are used to lower the representation for
28# backends that cannot handle some of our higher-level instructions.
29#
30
31#
32# A temporary - a variable that will be allocated to a register after we're
33# done.
34#
35
36class Node
37 def replaceTemporariesWithRegisters(kind)
38 mapChildren {
39 | node |
40 node.replaceTemporariesWithRegisters(kind)
41 }
42 end
43end
44
45class Tmp < NoChildren
46 attr_reader :firstMention, :lastMention
47 attr_reader :kind
48 attr_accessor :register
49
50 def initialize(codeOrigin, kind)
51 super(codeOrigin)
52 @kind = kind
53 end
54
55 def dump
56 "$tmp#{object_id}"
57 end
58
59 def mention!(position)
60 if not @firstMention or position < @firstMention
61 @firstMention = position
62 end
63 if not @lastMention or position > @lastMention
64 @lastMention = position
65 end
66 end
67
68 def replaceTemporariesWithRegisters(kind)
69 if @kind == kind
70 raise "Did not allocate register to temporary at #{codeOriginString}" unless @register
71 @register
72 else
73 self
74 end
75 end
76
77 def address?
78 false
79 end
80
81 def label?
82 false
83 end
84
85 def immediate?
86 false
87 end
88
89 def register?
90 true
91 end
92end
93
94# Assign registers to temporaries, by finding which temporaries interfere
95# with each other. Note that this relies on temporary live ranges not crossing
96# basic block boundaries.
97
98def assignRegistersToTemporaries(list, kind, registers)
99 list.each_with_index {
100 | node, index |
101 node.filter(Tmp).uniq.each {
102 | tmp |
103 if tmp.kind == kind
104 tmp.mention! index
105 end
106 }
107 }
108
109 freeRegisters = registers.dup
110 list.each_with_index {
111 | node, index |
112 tmpList = node.filter(Tmp).uniq
113 tmpList.each {
114 | tmp |
115 if tmp.kind == kind and tmp.firstMention == index
116 raise "Could not allocate register to temporary at #{node.codeOriginString}" if freeRegisters.empty?
117 tmp.register = freeRegisters.pop
118 end
119 }
120 tmpList.each {
121 | tmp |
122 if tmp.kind == kind and tmp.lastMention == index
123 freeRegisters.push tmp.register
124 raise "Register allocation inconsistency at #{node.codeOriginString}" if freeRegisters.size > registers.size
125 end
126 }
127 }
128
129 list.map {
130 | node |
131 node.replaceTemporariesWithRegisters(kind)
132 }
133end
134