Kaynağa Gözat

Add shortcut for `unsigned_x/power_of_two` -> `unsigned_x >> log2(power_of_two)`

gingerBill 1 ay önce
ebeveyn
işleme
4cbcb3ace7
2 değiştirilmiş dosya ile 18 ekleme ve 0 silme
  1. 7 0
      src/common.cpp
  2. 11 0
      src/llvm_backend_expr.cpp

+ 7 - 0
src/common.cpp

@@ -80,6 +80,13 @@ gb_internal gb_inline bool is_power_of_two(i64 x) {
 	return !(x & (x-1));
 }
 
+gb_internal gb_inline bool is_power_of_two_u64(u64 x) {
+	if (x == 0) {
+		return false;
+	}
+	return !(x & (x-1));
+}
+
 gb_internal int isize_cmp(isize x, isize y) {
 	if (x < y) {
 		return -1;

+ 11 - 0
src/llvm_backend_expr.cpp

@@ -1153,6 +1153,17 @@ gb_internal LLVMValueRef lb_integer_division(lbProcedure *p, LLVMValueRef lhs, L
 				return zero;
 			}
 		} else {
+			if (!is_signed && lb_sizeof(type) <= 8) {
+				u64 v = cast(u64)LLVMConstIntGetZExtValue(rhs);
+				if (v == 1) {
+					return lhs;
+				} else if (is_power_of_two_u64(v)) {
+					u64 n = floor_log2(v);
+					LLVMValueRef bits = LLVMConstInt(type, n, false);
+					return LLVMBuildLShr(p->builder, lhs, bits, "");
+				}
+			}
+
 			return call(p->builder, lhs, rhs, "");
 		}
 	}