]> git.saurik.com Git - apple/javascriptcore.git/blob - ftl/FTLOutput.cpp
JavaScriptCore-7600.1.4.15.12.tar.gz
[apple/javascriptcore.git] / ftl / FTLOutput.cpp
1 /*
2 * Copyright (C) 2013 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 #include "config.h"
27 #include "FTLOutput.h"
28
29 #if ENABLE(FTL_JIT)
30
31 namespace JSC { namespace FTL {
32
33 Output::Output(LContext context)
34 : IntrinsicRepository(context)
35 , m_function(0)
36 , m_heaps(0)
37 , m_builder(llvm->CreateBuilderInContext(m_context))
38 , m_block(0)
39 , m_nextBlock(0)
40 {
41 }
42
43 Output::~Output()
44 {
45 llvm->DisposeBuilder(m_builder);
46 }
47
48 void Output::initialize(LModule module, LValue function, AbstractHeapRepository& heaps)
49 {
50 IntrinsicRepository::initialize(module);
51 m_function = function;
52 m_heaps = &heaps;
53 }
54
55 LBasicBlock Output::appendTo(LBasicBlock block, LBasicBlock nextBlock)
56 {
57 appendTo(block);
58 return insertNewBlocksBefore(nextBlock);
59 }
60
61 void Output::appendTo(LBasicBlock block)
62 {
63 m_block = block;
64
65 llvm->PositionBuilderAtEnd(m_builder, block);
66 }
67
68 LBasicBlock Output::newBlock(const char* name)
69 {
70 if (!m_nextBlock)
71 return appendBasicBlock(m_context, m_function, name);
72 return insertBasicBlock(m_context, m_nextBlock, name);
73 }
74
75 LValue Output::sensibleDoubleToInt(LValue value)
76 {
77 RELEASE_ASSERT(isX86());
78 return call(
79 x86SSE2CvtTSD2SIIntrinsic(),
80 insertElement(
81 insertElement(getUndef(vectorType(doubleType, 2)), value, int32Zero),
82 doubleZero, int32One));
83 }
84
85 LValue Output::load(TypedPointer pointer, LType refType)
86 {
87 LValue result = get(intToPtr(pointer.value(), refType));
88 pointer.heap().decorateInstruction(result, *m_heaps);
89 return result;
90 }
91
92 void Output::store(LValue value, TypedPointer pointer, LType refType)
93 {
94 LValue result = set(value, intToPtr(pointer.value(), refType));
95 pointer.heap().decorateInstruction(result, *m_heaps);
96 }
97
98 LValue Output::baseIndex(LValue base, LValue index, Scale scale, ptrdiff_t offset)
99 {
100 LValue accumulatedOffset;
101
102 switch (scale) {
103 case ScaleOne:
104 accumulatedOffset = index;
105 break;
106 case ScaleTwo:
107 accumulatedOffset = shl(index, intPtrOne);
108 break;
109 case ScaleFour:
110 accumulatedOffset = shl(index, intPtrTwo);
111 break;
112 case ScaleEight:
113 case ScalePtr:
114 accumulatedOffset = shl(index, intPtrThree);
115 break;
116 }
117
118 if (offset)
119 accumulatedOffset = add(accumulatedOffset, constIntPtr(offset));
120
121 return add(base, accumulatedOffset);
122 }
123
124 void Output::branch(LValue condition, LBasicBlock taken, Weight takenWeight, LBasicBlock notTaken, Weight notTakenWeight)
125 {
126 LValue branch = buildCondBr(m_builder, condition, taken, notTaken);
127
128 if (!takenWeight || !notTakenWeight)
129 return;
130
131 double total = takenWeight.value() + notTakenWeight.value();
132
133 setMetadata(
134 branch, profKind,
135 mdNode(
136 m_context, branchWeights,
137 constInt32(takenWeight.scaleToTotal(total)),
138 constInt32(notTakenWeight.scaleToTotal(total))));
139 }
140
141 void Output::crashNonTerminal()
142 {
143 call(intToPtr(constIntPtr(abort), pointerType(functionType(voidType))));
144 }
145
146 } } // namespace JSC::FTL
147
148 #endif // ENABLE(FTL_JIT)
149