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 31namespace JSC { namespace FTL { 32 33Output::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 43Output::~Output() 44{ 45 llvm->DisposeBuilder(m_builder); 46} 47 48void Output::initialize(LModule module, LValue function, AbstractHeapRepository& heaps) 49{ 50 IntrinsicRepository::initialize(module); 51 m_function = function; 52 m_heaps = &heaps; 53} 54 55LBasicBlock Output::appendTo(LBasicBlock block, LBasicBlock nextBlock) 56{ 57 appendTo(block); 58 return insertNewBlocksBefore(nextBlock); 59} 60 61void Output::appendTo(LBasicBlock block) 62{ 63 m_block = block; 64 65 llvm->PositionBuilderAtEnd(m_builder, block); 66} 67 68LBasicBlock 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 75LValue 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 85LValue 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 92void 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 98LValue 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 124void 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 141void Output::crashNonTerminal() 142{ 143 call(intToPtr(constIntPtr(abort), pointerType(functionType(voidType)))); 144} 145 146} } // namespace JSC::FTL 147 148#endif // ENABLE(FTL_JIT) 149 150