dart-sdk/runtime/platform/utils.h
kmillikin@google.com c70bcfcfa3 Support constant folding of instructions with constant smi values.
In sparse conditional constant propagation, replace instructions with
constant smi values with their constant value.  Extend the analysis to
understant shift and bitwise binary operations.

R=fschneider@google.com
BUG=

Review URL: https://codereview.chromium.org//10968058

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@12778 260f80e4-7a28-3924-810f-c04153c831b5
2012-09-24 13:14:54 +00:00

189 lines
4.9 KiB
C++

// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
#ifndef PLATFORM_UTILS_H_
#define PLATFORM_UTILS_H_
#include "platform/assert.h"
#include "platform/globals.h"
namespace dart {
class Utils {
public:
template<typename T>
static inline T Minimum(T x, T y) {
return x < y ? x : y;
}
template<typename T>
static inline T Maximum(T x, T y) {
return x > y ? x : y;
}
template<typename T>
static inline T Abs(T x) {
if (x < 0) return -x;
return x;
}
template<typename T>
static inline bool IsPowerOfTwo(T x) {
return (x & (x - 1)) == 0;
}
template<typename T>
static inline int ShiftForPowerOfTwo(T x) {
ASSERT(IsPowerOfTwo(x));
int num_shifts = 0;
while (x > 1) {
num_shifts++;
x = x >> 1;
}
return num_shifts;
}
template<typename T>
static inline bool IsAligned(T x, int n) {
ASSERT(IsPowerOfTwo(n));
return (x & (n - 1)) == 0;
}
template<typename T>
static inline bool IsAligned(T* x, int n) {
return IsAligned(reinterpret_cast<uword>(x), n);
}
template<typename T>
static inline T RoundDown(T x, int n) {
ASSERT(IsPowerOfTwo(n));
return (x & -n);
}
template<typename T>
static inline T* RoundDown(T* x, int n) {
return reinterpret_cast<T*>(RoundDown(reinterpret_cast<uword>(x), n));
}
template<typename T>
static inline T RoundUp(T x, int n) {
return RoundDown(x + n - 1, n);
}
template<typename T>
static inline T* RoundUp(T* x, int n) {
return reinterpret_cast<T*>(RoundUp(reinterpret_cast<uword>(x), n));
}
static uint32_t RoundUpToPowerOfTwo(uint32_t x);
static int CountOneBits(uint32_t x);
static int HighestBit(int64_t v);
static int CountTrailingZeros(uword x);
// Computes a hash value for the given string.
static uint32_t StringHash(const char* data, int length);
// Computes a hash value for the given word.
static uint32_t WordHash(word key);
// Check whether an N-bit two's-complement representation can hold value.
template<typename T>
static inline bool IsInt(int N, T value) {
ASSERT((0 < N) &&
(static_cast<unsigned int>(N) < (kBitsPerByte * sizeof(value))));
T limit = static_cast<T>(1) << (N - 1);
return (-limit <= value) && (value < limit);
}
template<typename T>
static inline bool IsUint(int N, T value) {
ASSERT((0 < N) &&
(static_cast<unsigned int>(N) < (kBitsPerByte * sizeof(value))));
T limit = static_cast<T>(1) << N;
return (0 <= value) && (value < limit);
}
// Check whether the magnitude of value fits in N bits, i.e., whether an
// (N+1)-bit sign-magnitude representation can hold value.
template<typename T>
static inline bool IsAbsoluteUint(int N, T value) {
ASSERT((0 < N) &&
(static_cast<unsigned int>(N) < (kBitsPerByte * sizeof(value))));
if (value < 0) value = -value;
return IsUint(N, value);
}
static inline int32_t Low16Bits(int32_t value) {
return static_cast<int32_t>(value & 0xffff);
}
static inline int32_t High16Bits(int32_t value) {
return static_cast<int32_t>(value >> 16);
}
static inline int32_t Low32Bits(int64_t value) {
return static_cast<int32_t>(value);
}
static inline int32_t High32Bits(int64_t value) {
return static_cast<int32_t>(value >> 32);
}
static inline int64_t LowHighTo64Bits(uint32_t low, int32_t high) {
return (static_cast<int64_t>(high) << 32) | (low & 0x0ffffffffLL);
}
static bool IsDecimalDigit(char c) {
return ('0' <= c) && (c <= '9');
}
static bool IsHexDigit(char c) {
return IsDecimalDigit(c)
|| (('A' <= c) && (c <= 'F'))
|| (('a' <= c) && (c <= 'f'));
}
static int HexDigitToInt(char c) {
ASSERT(IsHexDigit(c));
if (IsDecimalDigit(c)) return c - '0';
if (('A' <= c) && (c <= 'F')) return 10 + (c - 'A');
return 10 + (c - 'a');
}
static char IntToHexDigit(int i) {
ASSERT(0 <= i && i < 16);
if (i < 10) return static_cast<char>('0' + i);
return static_cast<char>('A' + (i - 10));
}
// Perform a range check, checking if
// offset + count <= length
// without the risk of integer overflow.
static inline bool RangeCheck(intptr_t offset,
intptr_t count,
intptr_t length) {
return offset >= 0 &&
count >= 0 &&
length >= 0 &&
count <= (length - offset);
}
};
} // namespace dart
#if defined(TARGET_OS_ANDROID)
#include "platform/utils_android.h"
#elif defined(TARGET_OS_LINUX)
#include "platform/utils_linux.h"
#elif defined(TARGET_OS_MACOS)
#include "platform/utils_macos.h"
#elif defined(TARGET_OS_WINDOWS)
#include "platform/utils_win.h"
#else
#error Unknown target os.
#endif
#endif // PLATFORM_UTILS_H_