MCPcopy Create free account
hub / github.com/apache/arrow / BuildAdd

Method BuildAdd

cpp/src/gandiva/decimal_ir.cc:272–335  ·  view source on GitHub ↗

The output scale/precision cannot be arbitrary values. The algo here depends on them to be the same as computed in DecimalTypeSql. TODO: enforce this.

Source from the content-addressed store, hash-verified

270/// to be the same as computed in DecimalTypeSql.
271/// TODO: enforce this.
272Status DecimalIR::BuildAdd() {
273 // Create fn prototype :
274 // int128_t
275 // add_decimal128_decimal128(int128_t x_value, int32_t x_precision, int32_t x_scale,
276 // int128_t y_value, int32_t y_precision, int32_t y_scale
277 // int32_t out_precision, int32_t out_scale)
278 auto i32 = types()->i32_type();
279 auto i128 = types()->i128_type();
280 auto function = BuildFunction(kAddFunction, i128,
281 {
282 {"x_value", i128},
283 {"x_precision", i32},
284 {"x_scale", i32},
285 {"y_value", i128},
286 {"y_precision", i32},
287 {"y_scale", i32},
288 {"out_precision", i32},
289 {"out_scale", i32},
290 });
291
292 auto arg_iter = function->arg_begin();
293 ValueFull x(&arg_iter[0], &arg_iter[1], &arg_iter[2]);
294 ValueFull y(&arg_iter[3], &arg_iter[4], &arg_iter[5]);
295 ValueFull out(nullptr, &arg_iter[6], &arg_iter[7]);
296
297 auto entry = llvm::BasicBlock::Create(*context(), "entry", function);
298 ir_builder()->SetInsertPoint(entry);
299
300 // CPP :
301 // if (out_precision < 38) {
302 // return AddFastPath(x, y)
303 // } else {
304 // ret = AddWithOverflowCheck(x, y)
305 // if (ret.overflow)
306 // return AddLarge(x, y)
307 // else
308 // return ret.value;
309 // }
310 llvm::Value* lt_max_precision = ir_builder()->CreateICmpSLT(
311 out.precision(), types()->i32_constant(DecimalTypeUtil::kMaxPrecision));
312 auto then_lambda = [&] {
313 // fast-path add
314 return AddFastPath(x, y);
315 };
316 auto else_lambda = [&] {
317 if (kUseOverflowIntrinsics) {
318 // do the add and check if there was overflow
319 auto ret = AddWithOverflowCheck(x, y, out);
320
321 // if there is an overflow, switch to the AddLarge codepath.
322 return BuildIfElse(
323 ret.overflow(), types()->i128_type(), [&] { return AddLarge(x, y, out); },
324 [&] { return ret.value(); });
325 } else {
326 return AddLarge(x, y, out);
327 }
328 };
329 auto value =

Callers 1

AddFunctionsMethod · 0.80

Calls 9

AddFastPathFunction · 0.85
AddLargeFunction · 0.85
overflowMethod · 0.80
typesFunction · 0.70
contextFunction · 0.70
ir_builderFunction · 0.70
OKFunction · 0.50
precisionMethod · 0.45
valueMethod · 0.45

Tested by

no test coverage detected