1/*
2 * Copyright (C) 2015-2017 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#pragma once
27
28#if ENABLE(B3_JIT)
29
30#include "AirArg.h"
31
32namespace JSC { namespace B3 { namespace Air {
33
34class Code;
35
36class TmpWidth {
37public:
38 TmpWidth();
39 TmpWidth(Code&);
40 ~TmpWidth();
41
42 void recompute(Code&);
43
44 // The width of a Tmp is the number of bits that you need to be able to track without some trivial
45 // recovery. A Tmp may have a "subwidth" (say, Width32 on a 64-bit system) if either of the following
46 // is true:
47 //
48 // - The high bits are never read.
49 // - The high bits are always zero.
50 //
51 // This doesn't tell you which of those properties holds, but you can query that using the other
52 // methods.
53 Width width(Tmp tmp) const
54 {
55 auto iter = m_width.find(tmp);
56 if (iter == m_width.end())
57 return minimumWidth(Arg(tmp).bank());
58 return std::min(iter->value.use, iter->value.def);
59 }
60
61 // Return the minimum required width for all defs/uses of this Tmp.
62 Width requiredWidth(Tmp tmp)
63 {
64 auto iter = m_width.find(tmp);
65 if (iter == m_width.end())
66 return minimumWidth(Arg(tmp).bank());
67 return std::max(iter->value.use, iter->value.def);
68 }
69
70 // This indirectly tells you how much of the tmp's high bits are guaranteed to be zero. The number of
71 // high bits that are zero are:
72 //
73 // TotalBits - defWidth(tmp)
74 //
75 // Where TotalBits are the total number of bits in the register, so 64 on a 64-bit system.
76 Width defWidth(Tmp tmp) const
77 {
78 auto iter = m_width.find(tmp);
79 if (iter == m_width.end())
80 return minimumWidth(Arg(tmp).bank());
81 return iter->value.def;
82 }
83
84 // This tells you how much of Tmp is going to be read.
85 Width useWidth(Tmp tmp) const
86 {
87 auto iter = m_width.find(tmp);
88 if (iter == m_width.end())
89 return minimumWidth(Arg(tmp).bank());
90 return iter->value.use;
91 }
92
93private:
94 struct Widths {
95 Widths() { }
96
97 Widths(Bank bank)
98 {
99 use = minimumWidth(bank);
100 def = minimumWidth(bank);
101 }
102
103 void dump(PrintStream& out) const;
104
105 Width use;
106 Width def;
107 };
108
109 HashMap<Tmp, Widths> m_width;
110};
111
112} } } // namespace JSC::B3::Air
113
114#endif // ENABLE(B3_JIT)
115