diff options
| author | Simon Hausmann <simon.hausmann@nokia.com> | 2012-02-24 16:36:50 +0100 |
|---|---|---|
| committer | Simon Hausmann <simon.hausmann@nokia.com> | 2012-02-24 16:36:50 +0100 |
| commit | ad0d549d4cc13433f77c1ac8f0ab379c83d93f28 (patch) | |
| tree | b34b0daceb7c8e7fdde4b4ec43650ab7caadb0a9 /Source/JavaScriptCore/offlineasm/opt.rb | |
| parent | 03e12282df9aa1e1fb05a8b90f1cfc2e08764cec (diff) | |
| download | qtwebkit-ad0d549d4cc13433f77c1ac8f0ab379c83d93f28.tar.gz | |
Imported WebKit commit bb52bf3c0119e8a128cd93afe5572413a8617de9 (http://svn.webkit.org/repository/webkit/trunk@108790)
Diffstat (limited to 'Source/JavaScriptCore/offlineasm/opt.rb')
| -rw-r--r-- | Source/JavaScriptCore/offlineasm/opt.rb | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/Source/JavaScriptCore/offlineasm/opt.rb b/Source/JavaScriptCore/offlineasm/opt.rb new file mode 100644 index 000000000..3170d3ae1 --- /dev/null +++ b/Source/JavaScriptCore/offlineasm/opt.rb @@ -0,0 +1,134 @@ +# Copyright (C) 2011 Apple Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +# THE POSSIBILITY OF SUCH DAMAGE. + +require "ast" + +# +# "Optimization" passes. These are used to lower the representation for +# backends that cannot handle some of our higher-level instructions. +# + +# +# A temporary - a variable that will be allocated to a register after we're +# done. +# + +class Node + def replaceTemporariesWithRegisters(kind) + mapChildren { + | node | + node.replaceTemporariesWithRegisters(kind) + } + end +end + +class Tmp < NoChildren + attr_reader :firstMention, :lastMention + attr_reader :kind + attr_accessor :register + + def initialize(codeOrigin, kind) + super(codeOrigin) + @kind = kind + end + + def dump + "$tmp#{object_id}" + end + + def mention!(position) + if not @firstMention or position < @firstMention + @firstMention = position + end + if not @lastMention or position > @lastMention + @lastMention = position + end + end + + def replaceTemporariesWithRegisters(kind) + if @kind == kind + raise "Did not allocate register to temporary at #{codeOriginString}" unless @register + @register + else + self + end + end + + def address? + false + end + + def label? + false + end + + def immediate? + false + end + + def register? + true + end +end + +# Assign registers to temporaries, by finding which temporaries interfere +# with each other. Note that this relies on temporary live ranges not crossing +# basic block boundaries. + +def assignRegistersToTemporaries(list, kind, registers) + list.each_with_index { + | node, index | + node.filter(Tmp).uniq.each { + | tmp | + if tmp.kind == kind + tmp.mention! index + end + } + } + + freeRegisters = registers.dup + list.each_with_index { + | node, index | + tmpList = node.filter(Tmp).uniq + tmpList.each { + | tmp | + if tmp.kind == kind and tmp.firstMention == index + raise "Could not allocate register to temporary at #{node.codeOriginString}" if freeRegisters.empty? + tmp.register = freeRegisters.pop + end + } + tmpList.each { + | tmp | + if tmp.kind == kind and tmp.lastMention == index + freeRegisters.push tmp.register + raise "Register allocation inconsistency at #{node.codeOriginString}" if freeRegisters.size > registers.size + end + } + } + + list.map { + | node | + node.replaceTemporariesWithRegisters(kind) + } +end + |
