gfx/angle/src/compiler/ForLoopUnroll.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

michael@0 1 //
michael@0 2 // Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
michael@0 3 // Use of this source code is governed by a BSD-style license that can be
michael@0 4 // found in the LICENSE file.
michael@0 5 //
michael@0 6
michael@0 7 #include "compiler/ForLoopUnroll.h"
michael@0 8
michael@0 9 namespace {
michael@0 10
michael@0 11 class IntegerForLoopUnrollMarker : public TIntermTraverser {
michael@0 12 public:
michael@0 13
michael@0 14 virtual bool visitLoop(Visit, TIntermLoop* node)
michael@0 15 {
michael@0 16 // This is called after ValidateLimitations pass, so all the ASSERT
michael@0 17 // should never fail.
michael@0 18 // See ValidateLimitations::validateForLoopInit().
michael@0 19 ASSERT(node);
michael@0 20 ASSERT(node->getType() == ELoopFor);
michael@0 21 ASSERT(node->getInit());
michael@0 22 TIntermAggregate* decl = node->getInit()->getAsAggregate();
michael@0 23 ASSERT(decl && decl->getOp() == EOpDeclaration);
michael@0 24 TIntermSequence& declSeq = decl->getSequence();
michael@0 25 ASSERT(declSeq.size() == 1);
michael@0 26 TIntermBinary* declInit = declSeq[0]->getAsBinaryNode();
michael@0 27 ASSERT(declInit && declInit->getOp() == EOpInitialize);
michael@0 28 ASSERT(declInit->getLeft());
michael@0 29 TIntermSymbol* symbol = declInit->getLeft()->getAsSymbolNode();
michael@0 30 ASSERT(symbol);
michael@0 31 TBasicType type = symbol->getBasicType();
michael@0 32 ASSERT(type == EbtInt || type == EbtFloat);
michael@0 33 if (type == EbtInt)
michael@0 34 node->setUnrollFlag(true);
michael@0 35 return true;
michael@0 36 }
michael@0 37
michael@0 38 };
michael@0 39
michael@0 40 } // anonymous namepsace
michael@0 41
michael@0 42 void ForLoopUnroll::FillLoopIndexInfo(TIntermLoop* node, TLoopIndexInfo& info)
michael@0 43 {
michael@0 44 ASSERT(node->getType() == ELoopFor);
michael@0 45 ASSERT(node->getUnrollFlag());
michael@0 46
michael@0 47 TIntermNode* init = node->getInit();
michael@0 48 ASSERT(init != NULL);
michael@0 49 TIntermAggregate* decl = init->getAsAggregate();
michael@0 50 ASSERT((decl != NULL) && (decl->getOp() == EOpDeclaration));
michael@0 51 TIntermSequence& declSeq = decl->getSequence();
michael@0 52 ASSERT(declSeq.size() == 1);
michael@0 53 TIntermBinary* declInit = declSeq[0]->getAsBinaryNode();
michael@0 54 ASSERT((declInit != NULL) && (declInit->getOp() == EOpInitialize));
michael@0 55 TIntermSymbol* symbol = declInit->getLeft()->getAsSymbolNode();
michael@0 56 ASSERT(symbol != NULL);
michael@0 57 ASSERT(symbol->getBasicType() == EbtInt);
michael@0 58
michael@0 59 info.id = symbol->getId();
michael@0 60
michael@0 61 ASSERT(declInit->getRight() != NULL);
michael@0 62 TIntermConstantUnion* initNode = declInit->getRight()->getAsConstantUnion();
michael@0 63 ASSERT(initNode != NULL);
michael@0 64
michael@0 65 info.initValue = evaluateIntConstant(initNode);
michael@0 66 info.currentValue = info.initValue;
michael@0 67
michael@0 68 TIntermNode* cond = node->getCondition();
michael@0 69 ASSERT(cond != NULL);
michael@0 70 TIntermBinary* binOp = cond->getAsBinaryNode();
michael@0 71 ASSERT(binOp != NULL);
michael@0 72 ASSERT(binOp->getRight() != NULL);
michael@0 73 ASSERT(binOp->getRight()->getAsConstantUnion() != NULL);
michael@0 74
michael@0 75 info.incrementValue = getLoopIncrement(node);
michael@0 76 info.stopValue = evaluateIntConstant(
michael@0 77 binOp->getRight()->getAsConstantUnion());
michael@0 78 info.op = binOp->getOp();
michael@0 79 }
michael@0 80
michael@0 81 void ForLoopUnroll::Step()
michael@0 82 {
michael@0 83 ASSERT(mLoopIndexStack.size() > 0);
michael@0 84 TLoopIndexInfo& info = mLoopIndexStack[mLoopIndexStack.size() - 1];
michael@0 85 info.currentValue += info.incrementValue;
michael@0 86 }
michael@0 87
michael@0 88 bool ForLoopUnroll::SatisfiesLoopCondition()
michael@0 89 {
michael@0 90 ASSERT(mLoopIndexStack.size() > 0);
michael@0 91 TLoopIndexInfo& info = mLoopIndexStack[mLoopIndexStack.size() - 1];
michael@0 92 // Relational operator is one of: > >= < <= == or !=.
michael@0 93 switch (info.op) {
michael@0 94 case EOpEqual:
michael@0 95 return (info.currentValue == info.stopValue);
michael@0 96 case EOpNotEqual:
michael@0 97 return (info.currentValue != info.stopValue);
michael@0 98 case EOpLessThan:
michael@0 99 return (info.currentValue < info.stopValue);
michael@0 100 case EOpGreaterThan:
michael@0 101 return (info.currentValue > info.stopValue);
michael@0 102 case EOpLessThanEqual:
michael@0 103 return (info.currentValue <= info.stopValue);
michael@0 104 case EOpGreaterThanEqual:
michael@0 105 return (info.currentValue >= info.stopValue);
michael@0 106 default:
michael@0 107 UNREACHABLE();
michael@0 108 }
michael@0 109 return false;
michael@0 110 }
michael@0 111
michael@0 112 bool ForLoopUnroll::NeedsToReplaceSymbolWithValue(TIntermSymbol* symbol)
michael@0 113 {
michael@0 114 for (TVector<TLoopIndexInfo>::iterator i = mLoopIndexStack.begin();
michael@0 115 i != mLoopIndexStack.end();
michael@0 116 ++i) {
michael@0 117 if (i->id == symbol->getId())
michael@0 118 return true;
michael@0 119 }
michael@0 120 return false;
michael@0 121 }
michael@0 122
michael@0 123 int ForLoopUnroll::GetLoopIndexValue(TIntermSymbol* symbol)
michael@0 124 {
michael@0 125 for (TVector<TLoopIndexInfo>::iterator i = mLoopIndexStack.begin();
michael@0 126 i != mLoopIndexStack.end();
michael@0 127 ++i) {
michael@0 128 if (i->id == symbol->getId())
michael@0 129 return i->currentValue;
michael@0 130 }
michael@0 131 UNREACHABLE();
michael@0 132 return false;
michael@0 133 }
michael@0 134
michael@0 135 void ForLoopUnroll::Push(TLoopIndexInfo& info)
michael@0 136 {
michael@0 137 mLoopIndexStack.push_back(info);
michael@0 138 }
michael@0 139
michael@0 140 void ForLoopUnroll::Pop()
michael@0 141 {
michael@0 142 mLoopIndexStack.pop_back();
michael@0 143 }
michael@0 144
michael@0 145 // static
michael@0 146 void ForLoopUnroll::MarkForLoopsWithIntegerIndicesForUnrolling(
michael@0 147 TIntermNode* root)
michael@0 148 {
michael@0 149 ASSERT(root);
michael@0 150
michael@0 151 IntegerForLoopUnrollMarker marker;
michael@0 152 root->traverse(&marker);
michael@0 153 }
michael@0 154
michael@0 155 int ForLoopUnroll::getLoopIncrement(TIntermLoop* node)
michael@0 156 {
michael@0 157 TIntermNode* expr = node->getExpression();
michael@0 158 ASSERT(expr != NULL);
michael@0 159 // for expression has one of the following forms:
michael@0 160 // loop_index++
michael@0 161 // loop_index--
michael@0 162 // loop_index += constant_expression
michael@0 163 // loop_index -= constant_expression
michael@0 164 // ++loop_index
michael@0 165 // --loop_index
michael@0 166 // The last two forms are not specified in the spec, but I am assuming
michael@0 167 // its an oversight.
michael@0 168 TIntermUnary* unOp = expr->getAsUnaryNode();
michael@0 169 TIntermBinary* binOp = unOp ? NULL : expr->getAsBinaryNode();
michael@0 170
michael@0 171 TOperator op = EOpNull;
michael@0 172 TIntermConstantUnion* incrementNode = NULL;
michael@0 173 if (unOp != NULL) {
michael@0 174 op = unOp->getOp();
michael@0 175 } else if (binOp != NULL) {
michael@0 176 op = binOp->getOp();
michael@0 177 ASSERT(binOp->getRight() != NULL);
michael@0 178 incrementNode = binOp->getRight()->getAsConstantUnion();
michael@0 179 ASSERT(incrementNode != NULL);
michael@0 180 }
michael@0 181
michael@0 182 int increment = 0;
michael@0 183 // The operator is one of: ++ -- += -=.
michael@0 184 switch (op) {
michael@0 185 case EOpPostIncrement:
michael@0 186 case EOpPreIncrement:
michael@0 187 ASSERT((unOp != NULL) && (binOp == NULL));
michael@0 188 increment = 1;
michael@0 189 break;
michael@0 190 case EOpPostDecrement:
michael@0 191 case EOpPreDecrement:
michael@0 192 ASSERT((unOp != NULL) && (binOp == NULL));
michael@0 193 increment = -1;
michael@0 194 break;
michael@0 195 case EOpAddAssign:
michael@0 196 ASSERT((unOp == NULL) && (binOp != NULL));
michael@0 197 increment = evaluateIntConstant(incrementNode);
michael@0 198 break;
michael@0 199 case EOpSubAssign:
michael@0 200 ASSERT((unOp == NULL) && (binOp != NULL));
michael@0 201 increment = - evaluateIntConstant(incrementNode);
michael@0 202 break;
michael@0 203 default:
michael@0 204 ASSERT(false);
michael@0 205 }
michael@0 206
michael@0 207 return increment;
michael@0 208 }
michael@0 209
michael@0 210 int ForLoopUnroll::evaluateIntConstant(TIntermConstantUnion* node)
michael@0 211 {
michael@0 212 ASSERT((node != NULL) && (node->getUnionArrayPointer() != NULL));
michael@0 213 return node->getIConst(0);
michael@0 214 }
michael@0 215

mercurial