-
Notifications
You must be signed in to change notification settings - Fork 1.2k
/
Copy pathValueRelativeOffset.cpp
117 lines (98 loc) · 3.66 KB
/
ValueRelativeOffset.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
//-------------------------------------------------------------------------------------------------------
// Copyright (C) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
//-------------------------------------------------------------------------------------------------------
#include "Backend.h"
const ValueNumber InvalidValueNumber = 0;
const ValueNumber ZeroValueNumber = 1;
const ValueNumber FirstNewValueNumber = ZeroValueNumber + 1;
ValueRelativeOffset::ValueRelativeOffset()
#if DBG
: baseValue(nullptr)
#endif
{
Assert(!IsValid());
}
ValueRelativeOffset::ValueRelativeOffset(const Value *const baseValue, const bool wasEstablishedExplicitly)
: baseValue(baseValue), offset(0), wasEstablishedExplicitly(wasEstablishedExplicitly)
{
Assert(baseValue);
Assert(IsValid());
}
ValueRelativeOffset::ValueRelativeOffset(const Value *const baseValue, const int offset, const bool wasEstablishedExplicitly)
: baseValue(baseValue), offset(offset), wasEstablishedExplicitly(wasEstablishedExplicitly)
{
Assert(baseValue);
Assert(IsValid());
}
#if DBG
bool ValueRelativeOffset::IsValid() const
{
return !!baseValue;
}
#endif
ValueNumber ValueRelativeOffset::BaseValueNumber() const
{
Assert(IsValid());
return baseValue->GetValueNumber();
}
StackSym *ValueRelativeOffset::BaseSym() const
{
Assert(IsValid());
Sym *const baseSym = baseValue->GetValueInfo()->GetSymStore();
return baseSym && baseSym->IsStackSym() ? baseSym->AsStackSym() : nullptr;
}
int ValueRelativeOffset::Offset() const
{
Assert(IsValid());
return offset;
}
void ValueRelativeOffset::SetOffset(const int offset)
{
Assert(IsValid());
this->offset = offset;
}
bool ValueRelativeOffset::WasEstablishedExplicitly() const
{
Assert(IsValid());
return wasEstablishedExplicitly;
}
void ValueRelativeOffset::SetWasEstablishedExplicitly()
{
Assert(IsValid());
wasEstablishedExplicitly = true;
}
bool ValueRelativeOffset::Add(const int n)
{
Assert(IsValid());
return !Int32Math::Add(offset, n, &offset);
}
template<bool Lower, bool Aggressive>
void ValueRelativeOffset::Merge(const ValueRelativeOffset &other)
{
Assert(IsValid());
Assert(other.IsValid());
Assert(BaseValueNumber() == other.BaseValueNumber());
if(!BaseSym() && other.BaseSym())
baseValue = other.baseValue;
MergeConstantValue<Lower, Aggressive>(other.offset);
if(other.wasEstablishedExplicitly == Aggressive)
wasEstablishedExplicitly = Aggressive;
}
template void ValueRelativeOffset::Merge<false, false>(const ValueRelativeOffset &other);
template void ValueRelativeOffset::Merge<false, true>(const ValueRelativeOffset &other);
template void ValueRelativeOffset::Merge<true, false>(const ValueRelativeOffset &other);
template void ValueRelativeOffset::Merge<true, true>(const ValueRelativeOffset &other);
template<bool Lower, bool Aggressive>
void ValueRelativeOffset::MergeConstantValue(const int constantValue)
{
Assert(IsValid());
// Merge down for a conservative lower bound or aggressive upper bound merge, or merge up for a conservative upper bound or
// aggressive lower bound merge
if(Lower ^ Aggressive ? constantValue < offset : constantValue > offset)
offset = constantValue;
}
template void ValueRelativeOffset::MergeConstantValue<false, false>(const int constantValue);
template void ValueRelativeOffset::MergeConstantValue<false, true>(const int constantValue);
template void ValueRelativeOffset::MergeConstantValue<true, false>(const int constantValue);
template void ValueRelativeOffset::MergeConstantValue<true, true>(const int constantValue);